El protocolo central del sistema X Window [1] [2] [3] es el protocolo base del sistema X Window , que es un sistema de ventanas en red para pantallas de mapa de bits que se utiliza para crear interfaces gráficas de usuario en Unix , sistemas operativos similares a Unix y otros . El sistema X Window se basa en un modelo cliente-servidor : un único servidor controla el hardware de entrada/salida , como la pantalla , el teclado y el ratón ; todos los programas de aplicación actúan como clientes , interactuando con el usuario y con los demás clientes a través del servidor. Esta interacción está regulada por el protocolo central del sistema X Window. Existen otros protocolos relacionados con el sistema X Window, ambos creados sobre el protocolo central del sistema X Window o como protocolos separados.
En el protocolo principal del sistema X Window, sólo se envían cuatro tipos de paquetes, de forma asíncrona, a través de la red: solicitudes, respuestas, eventos y errores. Las solicitudes las envía un cliente al servidor para pedirle que realice alguna operación (por ejemplo, crear una nueva ventana) y que le envíe de vuelta los datos que contiene. Las respuestas las envía el servidor para proporcionar dichos datos. Los eventos los envía el servidor para notificar a los clientes sobre la actividad del usuario u otros sucesos que les interesan. Los errores son paquetes enviados por el servidor para notificar a un cliente sobre los errores ocurridos durante el procesamiento de sus solicitudes. Las solicitudes pueden generar respuestas, eventos y errores; aparte de esto, el protocolo no exige un orden específico en el que se envíen los paquetes a través de la red. Existen algunas extensiones del protocolo principal, cada una con sus propias solicitudes, respuestas, eventos y errores.
X se originó en el MIT en 1984 (su [actualizar]versión actual, X11, apareció en septiembre de 1987). Sus diseñadores Bob Scheifler y Jim Gettys establecieron como principio inicial que su protocolo central era "crear mecanismos, no políticas". Como resultado, el protocolo central no especifica la interacción entre clientes y entre un cliente y el usuario. Estas interacciones son objeto de especificaciones independientes [4] , como las especificaciones ICCCM y freedesktop.org , y normalmente se aplican de forma automática mediante un conjunto de widgets determinado .
La comunicación entre el servidor y los clientes se realiza mediante el intercambio de paquetes a través de un canal . La conexión la establece el cliente (el protocolo no especifica cómo se inicia el cliente). El cliente también envía el primer paquete, que contiene el orden de bytes que se utilizará e información sobre la versión del protocolo y el tipo de autenticación que el cliente espera que utilice el servidor. El servidor responde enviando un paquete que indica la aceptación o el rechazo de la conexión, o con una solicitud de una autenticación adicional . Si se acepta la conexión, el paquete de aceptación contiene datos que el cliente puede utilizar en la interacción posterior con el servidor.
Una vez establecida la conexión, se intercambian cuatro tipos de paquetes entre el cliente y el servidor a través del canal:
Los paquetes de solicitud y respuesta tienen una longitud variable, mientras que los paquetes de eventos y errores tienen una longitud fija de 32 bytes .
El servidor numera secuencialmente los paquetes de solicitud en el momento en que los recibe: la primera solicitud de un cliente se numera con el número 1, la segunda con el 2, etc. Los 16 bits menos significativos del número secuencial de una solicitud se incluyen en los paquetes de respuesta y error generados por la solicitud, si los hay. También se incluyen en los paquetes de eventos para indicar el número secuencial de la solicitud que el servidor está procesando actualmente o acaba de terminar de procesar.
Lo que en la mayoría de las interfaces gráficas de usuario se suele denominar ventana , en el sistema X Window se denomina ventana de nivel superior . El término ventana también se utiliza para designar ventanas que se encuentran dentro de otra ventana, es decir, las subventanas de una ventana principal . Los elementos gráficos como botones , menús , iconos , etc. se pueden realizar mediante subventanas.
Un cliente puede solicitar la creación de una ventana. Más precisamente, puede solicitar la creación de una subventana de una ventana existente. Como resultado, las ventanas creadas por los clientes se organizan en 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 al iniciarse. Todas las demás 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 el escritorio virtual y se encuentra detrás de todas las demás ventanas.
No siempre se garantiza que el contenido de una ventana se conserve a lo largo del tiempo. En particular, el contenido de la ventana puede destruirse cuando la ventana se mueve, se redimensiona, se cubre con otras ventanas y, en general, se vuelve total o parcialmente no visible. En particular, el contenido se pierde si el servidor X no mantiene un almacenamiento de respaldo del contenido de la ventana. El cliente puede solicitar que se mantenga un almacenamiento de respaldo para una ventana, pero el servidor no tiene obligación de hacerlo. Por lo tanto, los clientes no pueden asumir que se mantenga el almacenamiento de respaldo. Si una parte visible de una ventana tiene un contenido no especificado, se envía un evento para notificar al cliente que el contenido de la ventana debe volver a dibujarse.
Cada ventana tiene un conjunto asociado de atributos , como la geometría de la ventana (tamaño y posición), la imagen de fondo, si se ha solicitado almacenamiento de respaldo para ella, etc. El protocolo incluye solicitudes para que un cliente inspeccione y cambie los atributos de una ventana.
Las ventanas pueden ser InputOutput
o InputOnly
. InputOutput
las ventanas pueden mostrarse en la pantalla y se utilizan para dibujar. InputOnly
las ventanas nunca se muestran en la pantalla y se utilizan solo para recibir entradas.
El marco decorativo y la barra de título (que posiblemente incluya botones) que se ven generalmente alrededor de las ventanas son creados por el administrador de ventanas , no por el cliente que crea la ventana. El administrador de ventanas también maneja la entrada relacionada con estos elementos, como el cambio de tamaño de la ventana cuando el usuario hace clic y arrastra el marco de la ventana. Los clientes generalmente operan en la ventana que crearon sin tener en cuenta los cambios operados por el administrador de ventanas. Un cambio que debe tener en cuenta es que la re-repartición de administradores de ventanas , que son casi todos los administradores de ventanas modernos, cambia el padre de las ventanas de nivel superior a una ventana que no es la raíz. Desde el punto de vista del protocolo central, el administrador de ventanas es un cliente, no diferente de las otras aplicaciones.
Los datos sobre una ventana se pueden obtener ejecutando el xwininfo
programa. Al pasarle el -tree
argumento de línea de comandos , este programa muestra el árbol de subventanas de una ventana, junto con sus identificadores y datos geométricos.
Un mapa de píxeles es una región de memoria que se puede utilizar para dibujar. A diferencia de las ventanas, los mapas de píxeles no se muestran automáticamente en la pantalla. Sin embargo, el contenido de un mapa de píxeles (o una parte de él) se puede transferir a una ventana y viceversa. Esto permite técnicas como el doble almacenamiento en búfer . La mayoría de las operaciones gráficas que se pueden realizar en ventanas también se pueden realizar en mapas de píxeles.
Las ventanas y los mapas de píxeles se denominan colectivamente elementos dibujables y sus datos de contenido residen en el servidor. Sin embargo, un cliente puede solicitar que el contenido de un elemento dibujable se transfiera del servidor al cliente o viceversa.
El cliente puede solicitar una serie de operaciones gráficas, como limpiar un área, copiar un área en otra, dibujar puntos, líneas, rectángulos y texto. Además de limpiar, todas las operaciones son posibles en todos los elementos dibujables, tanto ventanas como mapas de píxeles.
La mayoría de las solicitudes 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 de primer plano, el color de fondo, la fuente del texto y otros parámetros gráficos. Al solicitar 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 afecta al trazado de una línea.
El protocolo central especifica el uso de fuentes del lado del servidor. [5] Dichas fuentes se almacenan como archivos y el servidor accede a ellas directamente a través del sistema de archivos local o a través de la red desde otro programa llamado servidor de fuentes . Los clientes pueden solicitar la lista de fuentes disponibles para el servidor y pueden solicitar que el servidor cargue (si aún no lo hizo) o descargue (si no lo usan otros clientes) una fuente. Un cliente puede solicitar información general sobre una fuente (por ejemplo, el ascenso de la fuente) y el espacio que ocupa una cadena específica cuando se dibuja con una fuente específica.
Los nombres de las fuentes son cadenas arbitrarias a nivel del protocolo principal de X Window. Las convenciones de descripción de fuentes lógicas de X [6] especifican cómo se deben nombrar las fuentes según sus atributos. Estas convenciones también especifican los valores de las propiedades opcionales que se pueden adjuntar a las fuentes.
El xlsfonts
programa imprime la lista de fuentes almacenadas en el servidor. El xfontsel
programa muestra los glifos de las fuentes y permite al usuario seleccionar el nombre de una fuente para pegarlo en otra ventana.
Actualmente, el uso de fuentes del lado del servidor se considera obsoleto en favor de las fuentes del lado del cliente. [7] Estas fuentes son renderizadas por el cliente, no por el servidor, con el apoyo de las bibliotecas Xft o cairo y la extensión XRender . No se proporciona ninguna especificación sobre las fuentes del lado del cliente en el protocolo principal.
Todos los datos sobre ventanas, mapas de bits, fuentes, etc. se almacenan en el servidor. El cliente conoce los identificadores de estos objetos (números enteros que utiliza como nombres para ellos cuando interactúa con el servidor). Por ejemplo, si un cliente desea que se cree una ventana, solicita al servidor que cree una ventana con un identificador determinado. El identificador puede ser utilizado posteriormente por el cliente para solicitar, por ejemplo, que se dibuje una cadena en la ventana. Los siguientes objetos residen en el servidor y el cliente los conoce a través de un identificador numérico:
Window
Pixmap
Font
Colormap
(una tabla de colores, descrita a continuación)Graphic context
Estos objetos se denominan recursos . Cuando un cliente solicita la creación de uno de estos recursos, también especifica un identificador para él. Por ejemplo, para crear una nueva ventana, el cliente especifica tanto los atributos de la ventana (principal, ancho, alto, etc.) como el identificador que se asociará con la ventana.
Los identificadores son números enteros de 32 bits , con los tres bits más significativos iguales a cero. Cada cliente tiene su propio conjunto de identificadores que puede utilizar para crear nuevos recursos. El servidor especifica este conjunto como dos números enteros incluidos en el paquete de aceptación (el paquete que envía al cliente para informarle de que se acepta la conexión). Los clientes eligen los identificadores que se encuentran en este conjunto de forma que no entren en conflicto: dos objetos entre ventanas, mapas de píxeles, fuentes, mapas de colores y contextos gráficos no pueden tener el mismo identificador.
Una vez creado un recurso, el cliente utiliza su identificador para solicitar operaciones relacionadas con él al servidor. Algunas operaciones afectan al recurso en cuestión (por ejemplo, solicitudes para mover ventanas); otras solicitan datos del recurso almacenados en el servidor (por ejemplo, solicitudes de atributos de ventanas).
Los identificadores son exclusivos del servidor, no solo del cliente; por ejemplo, no hay dos ventanas que tengan el mismo identificador, incluso si las crean dos clientes diferentes. Un cliente puede acceder a cualquier objeto dado su identificador. En particular, también puede acceder a 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 al mismo servidor pueden usar el mismo identificador para referirse al mismo recurso. Por ejemplo, si un cliente crea una ventana con un identificador 0x1e00021
y pasa este número 0x1e00021
a otra aplicación (por cualquier medio disponible, por ejemplo, almacenando este número en un archivo que también sea accesible para la otra aplicación), esta 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, almacena su identificador en una variable de entorno y llama a Ghostscript ; este programa dibuja el contenido del archivo PostScript para mostrarlo en esta ventana. [8]
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 que no los destruya.
Los eventos son paquetes que el servidor envía a un cliente para comunicarle que ha ocurrido algo que podría interesarle. Por ejemplo, se envía un evento cuando el usuario presiona una tecla o hace clic en un botón del mouse. Los eventos no solo se utilizan para la entrada de datos: por ejemplo, se envían para indicar la creación de nuevas subventanas de una ventana determinada.
Cada evento es relativo a una ventana. Por ejemplo, si el usuario hace clic cuando el puntero está en una ventana, el evento será relativo a esa ventana. El paquete de eventos contiene el identificador de esa ventana.
Un cliente puede solicitar al servidor que envíe un evento a otro cliente; esto se utiliza para la comunicación entre clientes. Un evento de este tipo se genera, por ejemplo, cuando un cliente solicita el texto que está seleccionado en ese momento: este evento se envía al cliente que está manejando la ventana que contiene la selección.
El Expose
evento se envía cuando se destruye un área de una ventana y se hace visible su contenido. El contenido de una ventana puede destruirse en algunas condiciones, por ejemplo, si la ventana está cubierta y el servidor no mantiene un almacenamiento de respaldo. El servidor genera un Expose
evento para notificar al cliente que se debe dibujar una parte de la ventana.
La mayoría de los tipos de eventos se envían solo si el cliente manifestó previamente su interés en ellos. Esto se debe a que los clientes pueden estar interesados solo en algunos tipos de eventos. Por ejemplo, un cliente puede estar interesado en eventos relacionados con el teclado pero no en eventos relacionados con el mouse. Sin embargo, algunos tipos de eventos se envían a los clientes incluso si no los han solicitado específicamente.
Los clientes especifican qué tipo de eventos quieren recibir configurando un atributo de una ventana. Por ejemplo, para volver a dibujar una ventana cuando se ha destruido su contenido, un cliente debe recibir los Expose
eventos que le informan de que es necesario volver a dibujar la ventana. Sin embargo, solo se enviarán Expose
eventos al cliente si este ha indicado previamente su interés en estos eventos, lo que se hace configurando adecuadamente el atributo de máscara de evento de la ventana.
Diferentes clientes pueden solicitar eventos en la misma ventana. Incluso pueden establecer diferentes máscaras de eventos en la misma ventana. Por ejemplo, un cliente puede solicitar solo eventos de teclado en una ventana mientras que otro cliente solicita solo eventos de mouse en la misma ventana. Esto es posible porque el servidor, para cada ventana, mantiene una máscara de eventos separada para cada cliente. Sin embargo, hay algunos tipos de eventos que solo pueden ser seleccionados por un cliente a la vez para cada ventana. En particular, estos eventos informan sobre los clics de los botones del mouse y algunos cambios relacionados con la administración de ventanas.
El xev
programa muestra los eventos relativos a una ventana. En particular, xev -id WID
solicita todos los eventos posibles relativos a la ventana del identificador WID
y los imprime.
El siguiente es un posible ejemplo de interacción entre un servidor y un programa que crea una ventana con un recuadro negro y sale al presionar una tecla. En este ejemplo, el servidor no envía ninguna respuesta porque las solicitudes del cliente no generan respuestas. Estas solicitudes podrían generar errores.
0x0000002b
) y qué identificadores puede crear el cliente.0x00200000
(esta solicitud, al igual que las demás solicitudes de este ejemplo, no genera respuestas del servidor)0x0000002b
) con identificador 0x00200001
, tamaño 200x200, posición (10,10), etc.0x00200001
, especificando que está interesado en recibir Expose
eventos KeyPress
.0x00200001
que se asigne la ventana (se muestre en la pantalla)Expose
evento al clientePolyFillRectangle
solicitud con 0x00200001
contexto de ventana y gráfico.0x00200000
Si la ventana está cubierta por otra ventana y se descubre nuevamente, suponiendo que no se mantiene el almacenamiento de respaldo:
Expose
evento para indicarle al cliente que la ventana debe dibujarse nuevamente.PolyFillRectangle
solicitud.Si se presiona una tecla:
KeyPress
evento al cliente para notificarle que el usuario ha presionado una teclaA nivel de protocolo, un color se representa mediante un entero sin signo de 32 bits, denominado valor de píxel . Los siguientes elementos afectan la representación de los colores:
En el caso más sencillo, el mapa de colores es una tabla que contiene un triple RGB en cada fila. Un valor de píxel x
representa el color contenido en la x
fila -ésima de la tabla. Si el cliente puede cambiar las entradas en el mapa de colores, esta representación se identifica mediante la PseudoColor
clase visual . La clase visual StaticColor
es similar, pero el cliente no puede cambiar las entradas en el mapa de colores.
Hay un total de seis clases visuales posibles, cada una de las cuales identifica una forma diferente de representar un triple RGB con un valor de píxel. PseudoColor
y StaticColor
son dos. Otras dos son GrayScale
y StaticGray
, que se diferencian en que solo muestran tonos de gris.
Las dos clases visuales restantes se diferencian de las anteriores porque dividen los valores de píxel en tres partes y utilizan tres tablas independientes para la intensidad del rojo, el verde y el azul. Según esta representación del color, un valor de píxel se convierte en un triple RGB de la siguiente manera:
Este mecanismo requiere que el mapa de colores esté compuesto por tres tablas independientes, una para cada color primario . El resultado de la conversión sigue siendo un triple de valores de intensidad. Las clases visuales que utilizan esta representación son DirectColor
y TrueColor
, y difieren en si el cliente puede cambiar los mapas de colores o no.
Estos seis mecanismos para representar colores con valores de píxeles requieren algunos parámetros adicionales para funcionar. Estos parámetros se recopilan en un tipo visual , que contiene una clase visual y otros parámetros de la representación de colores. Cada servidor tiene un conjunto fijo de tipos visuales, cada uno asociado con un identificador numérico. Estos identificadores son números enteros sin signo de 32 bits, pero no son necesariamente diferentes de los identificadores de recursos o átomos.
Cuando se acepta la conexión de un cliente, el paquete de aceptación enviado por el servidor contiene una secuencia de bloques, cada uno de los cuales contiene información sobre una única pantalla. Para cada pantalla, el bloque relativo contiene una lista de otros bloques, cada uno relativo a una profundidad de color específica que admite la pantalla. Para cada profundidad admitida, esta lista contiene una lista de tipos visuales. Como resultado, a cada pantalla se le asocia un número de posibles profundidades, y a cada profundidad de cada pantalla se le asocia un número de posibles tipos visuales. Un tipo visual determinado se puede utilizar para más pantallas y para diferentes profundidades.
Para cada tipo visual, el paquete de aceptación contiene tanto su identificador como los parámetros reales que contiene (clase visual, etc.). El cliente almacena esta información, ya que no puede solicitarla posteriormente. Además, los clientes no pueden cambiar ni crear nuevos tipos visuales. Las solicitudes de creación de una nueva ventana incluyen la profundidad y el identificador del tipo visual que se utilizará para representar los colores de esta ventana.
Los mapas de colores se utilizan independientemente de si el hardware que controla la pantalla (por ejemplo, una tarjeta gráfica ) utiliza una paleta , que es una tabla que también se utiliza para representar colores. Los servidores utilizan mapas de colores incluso si el hardware no utiliza una paleta. Siempre que el hardware utiliza paletas, solo se puede instalar un número limitado de mapas de colores. En particular, se instala un mapa de colores cuando el hardware muestra colores de acuerdo con él. Un cliente puede solicitar al servidor que instale un mapa de colores. Sin embargo, esto puede requerir la desinstalación de otro mapa de colores: el efecto es que las ventanas que utilizan el mapa de colores desinstalado no se muestran con el color correcto, un efecto denominado color intermitente o technicolor . Este problema se puede resolver utilizando mapas de colores estándar , que son mapas de colores con una asociación predecible entre valores de píxeles y colores. Gracias a esta propiedad, los mapas de colores estándar pueden ser utilizados por diferentes aplicaciones.
La creación de mapas de colores está regulada por la convención ICCCM . Los mapas de colores estándar están regulados por la ICCCM y por la especificación Xlib .
Una parte del sistema de color X es el Sistema de gestión de color X (xcms). Este sistema se introdujo con X11R6 Release 5 en 1991. Este sistema consta de varias características adicionales en xlib, que se encuentran en la serie de funciones Xcms*. Este sistema define esquemas de color independientes del dispositivo que se pueden convertir en sistemas RGB dependientes del dispositivo. El sistema consta de las funciones Xcms* de xlib y también de la Convención de caracterización de color del dispositivo X (XDCCC), que describe cómo convertir los diversos sistemas de color independientes del dispositivo en sistemas de color RGB dependientes del dispositivo. Este sistema admite los sistemas de color CIEXYZ , xyY , CIELUV y CIELAB , así como los sistemas de color TekHVC. [1], [2]
Los átomos son números enteros de 32 bits que representan cadenas . Los diseñadores del protocolo introdujeron los átomos porque representan cadenas de un tamaño corto y fijo: [9] aunque una cadena puede tener una longitud arbitraria, un átomo es siempre un número entero de 32 bits. La brevedad de los átomos se aprovechó al exigir su uso en los tipos de paquetes que es probable que se envíen muchas veces con las mismas cadenas; esto da como resultado un uso más eficiente de la red. El tamaño fijo de los átomos se aprovechó al especificar un tamaño fijo para los eventos, es decir, 32 bytes: los paquetes de tamaño fijo pueden contener átomos, mientras que no pueden contener cadenas largas.
Precisamente, los átomos son identificadores de cadenas almacenadas en el servidor. Son similares a los identificadores de recursos (Windows, Pixmaps, etc.) pero se diferencian de ellos en dos aspectos. En primer lugar, los identificadores de los átomos son elegidos por el servidor, no por el cliente. En otras palabras, cuando un cliente solicita la creación de un nuevo átomo, sólo envía al servidor la cadena a almacenar, no su identificador; este identificador es elegido por el servidor y enviado de vuelta como respuesta al cliente. La segunda diferencia importante entre recursos y átomos es que los átomos no están asociados a clientes. Una vez creado, un átomo sobrevive hasta que el servidor se cierra o se reinicia (este no es el comportamiento predeterminado de los recursos).
Los átomos son identificadores y, por lo tanto, son únicos. Sin embargo, un átomo y un identificador de recurso pueden coincidir. La cadena asociada a un átomo se llama nombre del átomo . El nombre de un átomo no se puede cambiar después de la creación, y no pueden haber dos átomos con el mismo nombre. Como resultado, el nombre de un átomo se usa comúnmente para indicar el átomo: “el átomo ABCD
” significa, más precisamente, “el átomo cuya cadena asociada es ABCD
.” o “el átomo cuyo nombre es ABCD
.” Un cliente puede solicitar la creación de un nuevo átomo y puede solicitar el átomo (el identificador) de una cadena dada. Algunos átomos están predefinidos (creados por el servidor con el identificador y la cadena dados).
Los átomos se utilizan para diversos fines, principalmente relacionados con la comunicación entre distintos clientes conectados al mismo servidor. En particular, se utilizan en asociación con las propiedades de las ventanas, que se describen a continuación.
La lista de todos los átomos que residen en un servidor se puede imprimir mediante el programa xlsatoms
. En particular, este programa imprime cada átomo (el identificador, es decir, un número) con su nombre (su cadena asociada).
Cada ventana tiene un conjunto predefinido de atributos y un conjunto de propiedades, todos almacenados en el servidor y accesibles para los clientes mediante las solicitudes correspondientes. Los atributos son datos sobre la ventana, como su tamaño, posición, color de fondo, etc. Las propiedades son datos arbitrarios adjuntos a una ventana. A diferencia de los atributos, las propiedades no tienen significado a nivel del protocolo principal de X Window. Un cliente puede almacenar datos arbitrarios en una propiedad de una ventana.
Una propiedad se caracteriza por un nombre, un tipo y un valor. Las propiedades son similares a las variables en los lenguajes de programación imperativa , en el sentido de que un cliente puede crear una nueva propiedad con un nombre y un tipo determinados y almacenar un valor en ella. Las propiedades están asociadas a ventanas: dos propiedades con el mismo nombre pueden existir en dos ventanas diferentes y tener tipos y valores diferentes.
El nombre, el tipo y el valor de una propiedad son cadenas; más precisamente, son átomos, es decir, cadenas almacenadas en el servidor y accesibles para los clientes a través de identificadores. Una aplicación cliente puede acceder a una propiedad determinada utilizando el identificador del átomo que contiene el nombre de la propiedad.
Las propiedades se utilizan principalmente para la comunicación entre clientes. Por ejemplo, la propiedad denominada WM_NAME
(la propiedad nombrada por el átomo cuya cadena asociada es "WM_NAME"
) se utiliza para almacenar el nombre de las ventanas. Los administradores de ventanas suelen leer esta propiedad para mostrar el nombre de las ventanas en su barra de título.
Algunos tipos de comunicación entre clientes utilizan propiedades de la ventana raíz. Por ejemplo, según la especificación del gestor de ventanas freedesktop , [10] los gestores de ventanas deberían almacenar el identificador de la ventana activa en ese momento en la propiedad _NET_ACTIVE_WINDOW
de la ventana raíz. Los recursos X , que contienen parámetros de los programas, también se almacenan en propiedades de la ventana raíz; de esta manera, todos los clientes pueden acceder a ellos, incluso si se ejecutan en diferentes equipos.
El xprop
programa 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.
En el sistema X Window, cada tecla física individual está asociada a un número en el rango de 8 a 255, llamado keycode ( código de tecla). Un keycode solo identifica una tecla, no un carácter o término en particular (por ejemplo, "Re Pág") entre los que pueden estar impresos en la tecla. Cada uno de estos caracteres o términos se identifica por un keysym ( símbolo de tecla). Mientras que un keycode solo depende de la tecla real que se presiona, un keysym puede depender, por ejemplo, de si también se presionó la tecla Shift u otro modificador .
Cuando se presiona o se suelta una tecla, el servidor envía eventos de tipo KeyPress
o KeyRelease
a los clientes correspondientes. Estos eventos contienen:
Por lo tanto, el servidor envía el código de tecla y el estado del modificador sin intentar traducirlos a un carácter específico. Es responsabilidad del cliente realizar esta conversión. Por ejemplo, un cliente puede recibir un evento que indique que se presionó una tecla determinada mientras el modificador Shift estaba presionado. Si esta tecla generaría normalmente el carácter "a", el cliente (y no el servidor) asocia este evento al carácter "A".
Si bien la traducción de códigos de teclas a símbolos de teclas la realiza el cliente, la tabla que representa esta asociación la mantiene el servidor. Al almacenar esta tabla en un lugar centralizado, todos los clientes pueden acceder a ella. Los clientes típicos solo solicitan esta asignación y la utilizan para decodificar el código de tecla y el campo de modificadores de un evento de tecla en un símbolo de tecla. Sin embargo, los clientes también pueden cambiar esta asignación a voluntad.
Un modificador es una tecla que, al presionarla, cambia la interpretación de otras teclas. Un modificador común es la tecla Shift : cuando se presiona la tecla que normalmente produce una "a" minúscula junto con Shift, produce una "A" mayúscula. Otros modificadores comunes son "Control", "Alt" y "Meta".
El servidor X trabaja con un máximo de ocho modificadores. Sin embargo, cada modificador puede estar asociado a más de una tecla. Esto es necesario porque muchos teclados tienen teclas duplicadas para algunos modificadores. Por ejemplo, muchos teclados tienen dos teclas "Shift" (una a la izquierda y otra a la derecha). Estas dos teclas producen dos códigos de tecla diferentes cuando se presionan, pero el servidor X asocia ambas con el modificador "Shift".
Para cada uno de los ocho modificadores, el servidor X mantiene una lista de los códigos de teclas que considera que son ese modificador. Por ejemplo, si la lista del primer modificador (el modificador "Shift") contiene el código de tecla , entonces el servidor X considera que 0x37
la tecla que produce el código de tecla es una tecla Shift.0x37
La lista de asignaciones de modificadores la mantiene el servidor X, pero cada cliente puede cambiarla. Por ejemplo, un cliente puede solicitar que se agregue la tecla "F1 " a la lista de modificadores "Shift". A partir de este momento, esta tecla se comporta como otro modificador de Shift. Sin embargo, el código de tecla correspondiente a F1 se sigue generando cuando se presiona esta tecla. Como resultado, F1 funciona como lo hacía antes (por ejemplo, se puede abrir una ventana de ayuda cuando se presiona), pero también funciona como la tecla Shift (presionar "a" en un editor de texto mientras F1 está presionada agrega "A" al texto actual).
El servidor X mantiene y utiliza una asignación de modificadores para los botones del ratón. Sin embargo, los botones solo se pueden permutar . Esto resulta útil sobre todo para intercambiar el botón más a la izquierda y el más a la derecha para usuarios zurdos .
El xmodmap
programa muestra y cambia las asignaciones de teclas, modificadores y botones del mouse.
Una captura es una condición en la que todos los eventos del teclado o del ratón se envían a un único cliente. Un cliente puede solicitar una captura del teclado, del ratón o de ambos: si el servidor cumple la solicitud, todos los eventos del teclado o del ratón se envían al cliente que realiza la captura hasta que se libere la captura. Los demás clientes no recibirán estos eventos.
Al solicitar una captura, un cliente especifica una ventana de captura : todos los eventos se envían al cliente que realiza la captura como si fueran relativos a la ventana de captura. Sin embargo, los demás clientes no reciben eventos incluso si los han seleccionado en la ventana de captura. Hay dos tipos de capturas:
Un cliente puede establecer una captura sobre el teclado, el puntero o ambos. Una solicitud de captura puede incluir una solicitud de congelamiento del teclado o del puntero. La diferencia entre la captura y el congelamiento es que la captura cambia el destinatario de los eventos, mientras que el congelamiento detiene su entrega por completo. Cuando un dispositivo está congelado, los eventos que genera se almacenan en una cola para ser entregados como de costumbre cuando finaliza el congelamiento.
En el caso de los eventos de puntero, un parámetro adicional afecta la entrega de eventos: una máscara de evento, que especifica qué tipos de eventos se deben entregar y cuáles se deben descartar.
Las solicitudes de captura incluyen un campo para especificar qué sucede con los eventos que se enviarían al cliente que realiza la captura incluso si no hubiera establecido la captura. En particular, el cliente puede solicitar que se envíen como de costumbre o de acuerdo con la captura. Estas dos condiciones no son las mismas, tal como pueden parecer. Por ejemplo, un cliente que normalmente recibiría los eventos del teclado en una primera ventana puede solicitar que el teclado sea capturado por una segunda ventana. Los eventos que normalmente se enviarían a la primera ventana pueden o no ser redirigidos a la ventana de captura, dependiendo del parámetro en la solicitud de captura.
Un cliente también puede solicitar la captura de todo el servidor. En este caso, el servidor no procesará ninguna solicitud, excepto las que provengan del cliente que realiza la captura.
Existen otras solicitudes y eventos en el protocolo principal. El primer tipo de solicitudes es relativo a la relación padre-hijo entre ventanas: un cliente puede solicitar cambiar el padre de una ventana, o puede solicitar información sobre la paternidad de ventanas. Otras solicitudes son relativas a la selección , que sin embargo está gobernada principalmente por otros protocolos. Otras solicitudes son sobre el foco de entrada y la forma del puntero . Un cliente también puede solicitar que se elimine al propietario de un recurso (ventana, mapa de píxeles, etc.), lo que hace que el servidor finalice la conexión con él. Finalmente, un cliente puede enviar una solicitud de no operación al servidor.
El protocolo principal de X Window fue diseñado para ser extensible. El protocolo principal especifica un mecanismo para consultar las extensiones disponibles y cómo se generan las solicitudes de extensión, los eventos y los paquetes de errores.
En particular, un cliente puede solicitar la lista de todas las extensiones disponibles para los datos relativos a una extensión específica. Los paquetes de extensiones son similares a los paquetes del protocolo principal. El protocolo principal especifica que los paquetes de solicitud, evento y error contienen un entero que indica su tipo (por ejemplo, la solicitud para crear una nueva ventana se numera con el número 1). Un rango de estos enteros se reserva para las extensiones.
Cuando el cliente establece inicialmente una conexión con el servidor, el servidor puede responder aceptando la conexión, rechazándola o solicitando autenticación . Una solicitud de autenticación contiene el nombre del método de autenticación que se utilizará. El protocolo principal no especifica el proceso de autenticación, que depende del tipo de autenticación utilizado, excepto que finaliza con el envío por parte del servidor de un paquete de aceptación o rechazo.
Durante la interacción habitual entre un cliente y un servidor, las únicas solicitudes relacionadas con la autenticación se refieren al método de acceso basado en host . En particular, un cliente puede solicitar que se habilite este método y puede solicitar la lectura y modificación de la lista de hosts ( clientes ) que están autorizados a conectarse. Las aplicaciones típicas no utilizan estas solicitudes; el xhost
programa las utiliza para dar a un usuario o a un script acceso a la lista de acceso de host. El método de acceso basado en host se considera inseguro.
La mayoría de los programas cliente se comunican con el servidor a través de la biblioteca cliente Xlib . En particular, la mayoría de los clientes utilizan bibliotecas como Xaw , Motif , GTK+ o Qt , que a su vez utilizan Xlib para interactuar con el servidor. El uso de Xlib tiene los siguientes efectos:
XFlush
;XGetWindowAttributes
;XNextEvent
) y la llamada se bloquea (por ejemplo, XNextEvent
se bloquea si la cola está vacía).Las bibliotecas de nivel superior como Xt (que a su vez es utilizada por Xaw y Motif ) permiten al programa cliente especificar las funciones de devolución de llamada asociadas con algunos eventos; la biblioteca se encarga de sondear la cola de eventos y llamar a la función apropiada cuando es necesario; algunos eventos como los que indican la necesidad de volver a dibujar una ventana son manejados internamente por Xt.
Las bibliotecas de nivel inferior, como XCB , proporcionan acceso asincrónico al protocolo, lo que permite ocultar mejor la latencia.
El protocolo principal del sistema X Window no establece normas sobre la comunicación entre clientes y no especifica cómo se utilizan las ventanas para formar los elementos visuales que son comunes en las interfaces gráficas de usuario ( botones , menús , etc.). Los elementos de la interfaz gráfica de usuario están definidos por bibliotecas de cliente que implementan kits de herramientas de widgets . La comunicación entre clientes está cubierta por otros estándares como las especificaciones ICCCM y freedesktop . [10]
La comunicación entre clientes es relevante para las selecciones, los buffers de corte y la función de arrastrar y soltar , que son los métodos que utiliza un usuario para transferir datos de una ventana a otra. Dado que las ventanas pueden ser controladas por diferentes programas, es necesario un protocolo para intercambiar estos datos. La comunicación entre clientes también es relevante para los administradores de ventanas X , que son programas que controlan la apariencia de las ventanas y el aspecto general de la interfaz gráfica de usuario.
Otra cuestión en la que la comunicación entre clientes es hasta cierto punto relevante es la gestión de sesiones .
El modo en que se inicia una sesión de usuario es otro tema que no está contemplado en el protocolo principal. Normalmente, esto lo realiza automáticamente el administrador de pantalla X. Sin embargo, el usuario también puede iniciar una sesión manualmente ejecutando los programas xinit o startx .