Protocolo central do X Window System - X Window System core protocol

Image
O logotipo do X Window System

O protocolo central do X Window System é o protocolo básico do X Window System , que é um sistema de janelas em rede para exibições de bitmap usado para construir interfaces gráficas de usuário em Unix , semelhantes a Unix e outros sistemas operacionais . O X Window System é baseado em um modelo cliente-servidor : um único servidor controla o hardware de entrada / saída , como a tela , o teclado e o mouse ; todos os programas aplicativos atuam como clientes , interagindo com o usuário e com os demais clientes por meio do servidor. Essa interação é regulada pelo protocolo central do X Window System. Existem outros protocolos relacionados ao Sistema X Window, ambos construídos no topo do protocolo central do Sistema X Window ou como protocolos separados.

No protocolo central do X Window System, apenas quatro tipos de pacotes são enviados, de forma assíncrona , pela rede: solicitações, respostas, eventos e erros. As solicitações são enviadas por um cliente ao servidor para solicitar que ele execute alguma operação (por exemplo, criar uma nova janela) e para enviar de volta os dados que contém. As respostas são enviadas pelo servidor para fornecer esses dados. Os eventos são enviados pelo servidor para notificar os clientes sobre a atividade do usuário ou outras ocorrências em que estejam interessados. Erros são pacotes enviados pelo servidor para notificar um cliente sobre erros ocorridos durante o processamento de suas solicitações. As solicitações podem gerar respostas, eventos e erros; além disso, o protocolo não exige uma ordem específica na qual os pacotes são enviados pela rede. Existem algumas extensões para o protocolo principal, cada uma com suas próprias solicitações, respostas, eventos e erros.

O X se originou no MIT em 1984 (seu lançamento atual, o X11, apareceu em setembro de 1987). Seus projetistas Bob Scheifler e Jim Gettys estabeleceram como princípio inicial que seu protocolo central era "criar mecanismo, não política". Como resultado, o protocolo principal não especifica a interação entre clientes e entre um cliente e o usuário. Essas interações estão sujeitas a especificações separadas, como as especificações ICCCM e freedesktop.org , e normalmente são aplicadas automaticamente usando um determinado conjunto de widgets .

Visão geral

Image
Neste exemplo, o servidor X obtém a entrada de um teclado e mouse e exibe em uma tela. Um navegador da web e um emulador de terminal são executados na estação de trabalho do usuário, e um emulador de terminal é executado em um servidor remoto, mas sob o controle da máquina do usuário. Observe que o aplicativo remoto é executado da mesma forma que seria executado localmente.

A comunicação entre o servidor e os clientes é feita pela troca de pacotes em um canal . A conexão é estabelecida pelo cliente (como o cliente é iniciado não é especificado no protocolo). O cliente também envia o primeiro pacote, contendo a ordem de bytes a ser usada e informações sobre a versão do protocolo e o tipo de autenticação que o cliente espera que o servidor use. O servidor responde enviando de volta um pacote declarando a aceitação ou recusa da conexão, ou com um pedido de autenticação posterior . Se a conexão for aceita, o pacote de aceitação conterá dados para o cliente usar na interação subsequente com o servidor.

Image
Um exemplo de interação entre um cliente e um servidor.

Depois que a conexão é estabelecida, quatro tipos de pacotes são trocados entre o cliente e o servidor através do canal:

  1. Solicitação: o cliente solicita informações do servidor ou solicita que ele execute uma ação.
  2. Responder: o servidor responde a uma solicitação. Nem todos os pedidos geram respostas.
  3. Evento: O servidor informa o cliente sobre um evento, como entrada de teclado ou mouse, uma janela sendo movida, redimensionada ou exposta, etc.
  4. Erro: o servidor envia um pacote de erro se uma solicitação for inválida. Como as solicitações são enfileiradas, os pacotes de erro gerados por uma solicitação podem não ser enviados imediatamente.

Os pacotes de solicitação e resposta têm comprimento variável, enquanto os pacotes de evento e erro têm comprimento fixo de 32 bytes .

Os pacotes de pedidos são numerados sequencialmente pelo servidor assim que os recebe: o primeiro pedido de um cliente é numerado 1, o segundo 2, etc. Os 16 bits menos significativos do número sequencial de um pedido são incluídos na resposta e no erro pacotes gerados pela solicitação, se houver. Eles também são incluídos em pacotes de eventos para indicar o número sequencial da solicitação que o servidor está processando atualmente ou que acabou de processar.

janelas

O que normalmente é chamado de janela na maioria das interfaces gráficas do usuário é chamado de janela de nível superior no X Window System. O termo janela também é usado para denotar janelas que ficam dentro de outra janela, ou seja, as subjanelas de uma janela pai . Elementos gráficos como botões , menus , ícones , etc. podem ser realizados usando subjanelas.

Image
Uma possível localização de algumas janelas: 1 é a janela raiz, que cobre toda a tela; 2 e 3 são janelas de nível superior; 4 e 5 são subjanelas de 2. As partes de uma janela que estão fora de seu pai não são visíveis.

Um cliente pode solicitar a criação de uma janela. Mais precisamente, pode solicitar a criação de uma subjanela de uma janela existente. Como resultado, as janelas criadas pelos clientes são organizadas em uma árvore (uma hierarquia). A raiz desta árvore é a janela raiz , que é uma janela especial criada automaticamente pelo servidor na inicialização. Todas as outras janelas são direta ou indiretamente subjanelas da janela raiz. As janelas de nível superior são as subjanelas diretas da janela raiz. Visivelmente, a janela raiz é tão grande quanto a área de trabalho virtual e fica atrás de todas as outras janelas.

Nem sempre é garantido que o conteúdo de uma janela será preservado ao longo do tempo. Em particular, o conteúdo da janela pode ser destruído quando a janela é movida, redimensionada, coberta por outras janelas e, em geral, totalmente ou parcialmente invisível. Em particular, o conteúdo é perdido se o servidor X não estiver mantendo um armazenamento de apoio do conteúdo da janela. O cliente pode solicitar a manutenção de uma loja de apoio para uma janela, mas o servidor não tem obrigação de o fazer. Portanto, os clientes não podem presumir que o armazenamento de apoio seja mantido. Se uma parte visível de uma janela tiver um conteúdo não especificado, um evento é enviado para notificar o cliente de que o conteúdo da janela deve ser desenhado novamente.

Cada janela tem um conjunto associado de atributos , como a geometria da janela (tamanho e posição), a imagem de fundo, se o armazenamento de apoio foi solicitado para ela, etc. O protocolo inclui solicitações para um cliente inspecionar e alterar os atributos de uma janela.

O Windows pode ser InputOutput ou InputOnly . InputOutput as janelas podem ser mostradas na tela e são usadas para desenhar. InputOnly as janelas nunca são mostradas na tela e são usadas apenas para receber entradas.

Image
Anatomia de uma janela FVWM . A área em branco é a janela criada e vista pelo aplicativo cliente.

A moldura decorativa e a barra de título (possivelmente incluindo botões) que geralmente são vistas ao redor das janelas são criadas pelo gerenciador de janelas , não pelo cliente que cria a janela. O gerenciador de janelas também lida com a entrada relacionada a esses elementos, como redimensionar a janela quando o usuário clica e arrasta a moldura da janela. Os clientes geralmente operam na janela que criaram, desconsiderando as alterações operadas pelo gerenciador de janelas. Uma mudança que deve ser levada em consideração é que os gerenciadores de janelas de novo pai , que quase todos os gerenciadores de janelas modernos são, mudam o pai das janelas de nível superior para uma janela que não é a raiz. Do ponto de vista do protocolo principal, o gerenciador de janelas é um cliente, não diferente dos outros aplicativos.

Os dados sobre uma janela podem ser obtidos executando o xwininfo programa. Passando o argumento da -tree linha de comando, este programa mostra a árvore de subjanelas de uma janela, junto com seus identificadores e dados geométricos.

Pixmaps e drawables

Um pixmap é uma região da memória que pode ser usada para desenhar. Ao contrário das janelas, os pixmaps não são mostrados automaticamente na tela. No entanto, o conteúdo de um pixmap (ou parte dele) pode ser transferido para uma janela e vice-versa. Isso permite técnicas como buffer duplo . A maioria das operações gráficas que podem ser feitas no Windows também podem ser feitas em pixmaps.

Windows e pixmaps são chamados coletivamente de drawables e seus dados de conteúdo residem no servidor. No entanto, um cliente pode solicitar que o conteúdo de um drawable seja transferido do servidor para o cliente ou vice-versa.

Contextos gráficos e fontes

O cliente pode solicitar uma série de operações gráficas, como limpar uma área, copiar uma área em outra, desenhar pontos, linhas, retângulos e texto. Além da limpeza, todas as operações são possíveis em todos os drawables, tanto janelas quanto pixmaps.

A maioria das solicitações de operações gráficas inclui um contexto gráfico , que é uma estrutura que contém os parâmetros das operações gráficas. Um contexto gráfico inclui a cor do primeiro plano, a cor do plano de fundo, a fonte do texto e outros parâmetros gráficos. Ao solicitar uma operação gráfica, o cliente inclui um contexto gráfico. Nem todos os parâmetros do contexto gráfico afetam a operação: por exemplo, a fonte não afeta o desenho de uma linha.

O protocolo principal especifica o uso de fontes do lado do servidor. Essas fontes são armazenadas como arquivos , e o servidor os acessa diretamente por meio do sistema de arquivos local ou pela rede de outro programa chamado servidor de fontes . Os clientes podem solicitar a lista de fontes disponíveis para o servidor e podem solicitar que uma fonte seja carregada (se já não estiver) ou descarregada (se não for usada por outros clientes) pelo servidor. Um cliente pode solicitar informações gerais sobre uma fonte (por exemplo, a ascensão da fonte) e o espaço que uma string específica ocupa quando desenhada com uma fonte específica.

Image
O xfontsel programa permite que o usuário visualize os glifos de uma fonte.

Os nomes das fontes são strings arbitrárias no nível do protocolo central do X Window. As convenções de descrição de fonte lógica X especificam como as fontes devem ser nomeadas de acordo com seus atributos. Essas convenções também especificam os valores das propriedades opcionais que podem ser anexadas às fontes.

O xlsfonts programa imprime a lista de fontes armazenadas no servidor. O xfontsel programa mostra os glifos das fontes e permite ao usuário selecionar o nome de uma fonte para colá-la em outra janela.

O uso de fontes do lado do servidor é atualmente considerado obsoleto em favor das fontes do lado do cliente. Essas fontes são renderizadas pelo cliente, não pelo servidor, com o suporte das bibliotecas Xft ou cairo e da extensão XRender . Nenhuma especificação sobre fontes do lado do cliente é fornecida no protocolo principal.

Recursos e identificadores

Todos os dados sobre janelas, pixmaps, fontes, etc. são armazenados no servidor. O cliente conhece os identificadores desses objetos - inteiros que usa como nomes para eles ao interagir com o servidor. Por exemplo, se um cliente deseja que uma janela seja criada, ele solicita que o servidor crie uma janela com um determinado identificador. O identificador pode ser usado posteriormente pelo cliente para solicitar, por exemplo, uma string a ser desenhada na janela. Os seguintes objetos residem no servidor e são conhecidos pelo cliente por meio de um identificador numérico:

  • Window
  • Pixmap
  • Font
  • Colormap (uma tabela de cores, descrita abaixo)
  • Graphic context

Esses objetos são chamados de recursos . Quando um cliente solicita a criação de um desses recursos, ele também especifica um identificador para ele. Por exemplo, para criar uma nova janela, o cliente especifica os atributos da janela (pai, largura, altura, etc.) e o identificador a ser associado à janela.

Os identificadores são inteiros de 32 bits com seus três bits mais significativos iguais a zero. Cada cliente tem seu próprio conjunto de identificadores que pode usar para criar novos recursos. Este conjunto é especificado pelo servidor como dois inteiros incluídos no pacote de aceitação (o pacote que ele envia ao cliente para informá-lo de que a conexão é aceita). Os clientes escolhem os identificadores que estão neste conjunto de forma que não entrem em conflito: dois objetos entre janelas, pixmaps, fontes, mapas de cores e contextos gráficos não podem ter o mesmo identificador.

Depois que um recurso é criado, seu identificador é usado pelo cliente para solicitar operações sobre ele ao servidor. Algumas operações afetam o recurso fornecido (por exemplo, solicitações para mover janelas); outros solicitam dados de recursos armazenados no servidor (por exemplo, solicitações de atributos de janelas).

Os identificadores são exclusivos do servidor, não apenas do cliente; por exemplo, duas janelas não têm o mesmo identificador, mesmo se criadas por dois clientes diferentes. Um cliente pode acessar qualquer objeto com seu identificador. Em particular, ele também pode acessar recursos criados por qualquer outro cliente, mesmo se seus identificadores estiverem fora do conjunto de identificadores que ele pode criar.

Como resultado, dois clientes conectados ao mesmo servidor podem usar o mesmo identificador para se referir ao mesmo recurso. Por exemplo, se um cliente cria uma janela de identificador 0x1e00021 e passa esse número 0x1e00021 para outro aplicativo (por qualquer meio disponível, por exemplo, armazenando este número em um arquivo que também é acessível para outro aplicativo), este outro aplicativo é capaz de operar na mesma janela. Esta possibilidade é, por exemplo, explorada pela versão X Window do Ghostview : este programa cria uma subjanela, armazenando seu identificador em uma variável de ambiente , e chama Ghostscript ; este programa desenha o conteúdo do arquivo PostScript para mostrar nesta janela.

Os recursos são normalmente destruídos quando o cliente que os criou fecha a conexão com o servidor. No entanto, antes de fechar a conexão, um cliente pode solicitar ao servidor que não os destrua.

Eventos

Os eventos são pacotes enviados pelo servidor a um cliente para comunicar que aconteceu algo em que o cliente pode estar interessado. Por exemplo, um evento é enviado quando o usuário pressiona uma tecla ou clica em um botão do mouse. Os eventos não são usados ​​apenas para entrada: por exemplo, os eventos são enviados para indicar a criação de novas subjanelas de uma determinada janela.

Cada evento é relativo a uma janela. Por exemplo, se o usuário clicar quando o ponteiro estiver em uma janela, o evento será relativo a essa janela. O pacote de eventos contém o identificador dessa janela.

Um cliente pode solicitar ao servidor o envio de um evento a outro cliente; isso é usado para comunicação entre clientes. Tal evento é gerado, por exemplo, quando um cliente solicita o texto que está selecionado no momento: este evento é enviado ao cliente que está controlando a janela que contém a seleção.

O Expose evento é enviado quando uma área de uma janela destruída e o conteúdo fica visível. O conteúdo de uma janela pode ser destruído em algumas condições, por exemplo, se a janela estiver coberta e o servidor não estiver mantendo um armazenamento de apoio. O servidor gera um Expose evento para notificar o cliente de que uma parte da janela deve ser desenhada.

Image
Um exemplo de evento: quando uma tecla é pressionada em uma janela, um evento é gerado e enviado a um cliente dependendo da máscara de evento de sua janela, que o cliente pode alterar.

A maioria dos tipos de eventos são enviados apenas se o cliente já declarou interesse neles. Isso ocorre porque os clientes podem estar interessados ​​apenas em alguns tipos de eventos. Por exemplo, um cliente pode estar interessado em eventos relacionados ao teclado, mas não em eventos relacionados ao mouse. No entanto, alguns tipos de eventos são enviados aos clientes, mesmo que eles não os tenham solicitado especificamente.

Os clientes especificam quais tipos de eventos desejam enviar, definindo um atributo de uma janela. Por exemplo, para redesenhar uma janela quando seu conteúdo foi destruído, um cliente deve receber os Expose eventos, que o informam que a janela precisa ser desenhada novamente. No entanto, o cliente receberá Expose eventos apenas se o cliente tiver declarado previamente seu interesse nesses eventos, o que é feito definindo apropriadamente o atributo de máscara de evento da janela.

Clientes diferentes podem solicitar eventos na mesma janela. Eles podem até definir máscaras de eventos diferentes na mesma janela. Por exemplo, um cliente pode solicitar apenas eventos de teclado em uma janela enquanto outro cliente solicita apenas eventos de mouse na mesma janela. Isso é possível porque o servidor, para cada janela, mantém uma máscara de eventos separada para cada cliente. No entanto, existem alguns tipos de eventos que só podem ser selecionados por um cliente por vez para cada janela. Em particular, esses eventos relatam cliques do botão do mouse e algumas alterações relacionadas ao gerenciamento de janelas.

O xev programa mostra os eventos relativos a uma janela. Em particular, xev -id WID solicita todos os eventos possíveis relativos à janela do identificador WID e os imprime.

Exemplo

A seguir está um exemplo possível de interação entre um servidor e um programa que cria uma janela com uma caixa preta e sai ao pressionar uma tecla. Neste exemplo, o servidor não envia nenhuma resposta porque as solicitações do cliente não geram respostas. Essas solicitações podem gerar erros.

  1. O cliente abre a conexão com o servidor e envia o pacote inicial especificando a ordem de bytes que está usando.
  2. O servidor aceita a conexão (nenhuma autorização está envolvida neste exemplo) enviando um pacote apropriado, que contém outras informações, como o identificador da janela raiz (por exemplo, 0x0000002b ) e quais identificadores o cliente pode criar.
  3. O cliente solicita a criação de um contexto gráfico padrão com identificador 0x00200000 (esta solicitação, como as outras solicitações deste exemplo, não gera respostas do servidor)
  4. O cliente solicita que o servidor crie uma janela de nível superior (ou seja, especifica que o pai seja a janela raiz 0x0000002b ) com identificador 0x00200001 , tamanho 200x200, posição (10,10), etc.
  5. O cliente solicita uma alteração nos atributos da janela 0x00200001 , especificando que tem interesse em recebimento Expose e KeyPress eventos.
  6. O cliente solicita que a janela 0x00200001 seja mapeada (mostrada na tela)
  7. Quando a janela fica visível e seu conteúdo precisa ser desenhado, o servidor envia ao cliente um Expose evento
  8. Em resposta a este evento, o cliente solicita que uma caixa seja desenhada, enviando uma PolyFillRectangle solicitação com janela 0x00200001 e contexto gráfico 0x00200000

Se a janela for coberta por outra janela e descoberta novamente, presumindo que o armazenamento de apoio não seja mantido:

  1. O servidor envia outro Expose evento para dizer ao cliente que a janela deve ser desenhada novamente
  2. O cliente redesenha a janela enviando uma PolyFillRectangle solicitação

Se uma tecla for pressionada:

  1. O servidor envia um KeyPress evento ao cliente para notificá-lo de que o usuário pressionou uma tecla
  2. O cliente reage de forma adequada (neste caso, ele termina)

Cores

No nível do protocolo, uma cor é representada por um inteiro sem sinal de 32 bits, denominado pixelvalue . Os seguintes elementos afetam a representação das cores:

  1. a profundidade da cor
  2. o mapa de cores , que é uma tabela contendo os valores de intensidade de vermelho, verde e azul
  3. o tipo visual , que especifica como a tabela é usada para representar cores

No caso mais fácil, o mapa de cores é uma tabela contendo um triplo RGB em cada linha. Um pixelvalue x representa a cor contida na x -ésima linha da tabela. Se o cliente puder alterar as entradas no mapa de cores, esta representação é identificada pela PseudoColor classe visual . A classe visual StaticColor é semelhante, mas o cliente não pode alterar as entradas no mapa de cores.

Há um total de seis classes visuais possíveis, cada uma identificando uma maneira diferente de representar um triplo RGB com um valor de pixel. PseudoColor e StaticColor são dois. Outros dois são GrayScale e StaticGray , que diferem por exibir apenas tons de cinza.

As duas classes visuais restantes diferem das anteriores porque quebram os valores dos pixels em três partes e usam três tabelas separadas para a intensidade de vermelho, verde e azul. De acordo com esta representação de cor, um valor de pixel é convertido em um triplo RGB da seguinte maneira:

  1. o valor do pixel é visto como uma sequência de bits
  2. esta sequência é quebrada em três partes
  3. cada um desses três pedaços de bits é visto como um inteiro e usado como um índice para encontrar um valor em cada uma das três tabelas separadas

Este mecanismo requer que o mapa de cores seja composto de três tabelas separadas, uma para cada cor primária . O resultado da conversão ainda é o triplo dos valores de intensidade. As classes visuais que usam essa representação são as DirectColor e TrueColor uns, diferindo se o cliente pode alterar os mapas de cores ou não.

Todos esses seis mecanismos para representar cores com valores de pixel requerem alguns parâmetros adicionais para funcionar. Esses parâmetros são coletados em um tipo visual , que contém uma classe visual e outros parâmetros da representação de cores. Cada servidor possui um conjunto fixo de tipos visuais, cada um associado a um identificador numérico. Esses identificadores são inteiros sem sinal de 32 bits, mas não são necessariamente diferentes dos identificadores de recursos ou átomos.

Quando a conexão de um cliente é aceita, o pacote de aceitação enviado pelo servidor contém uma sequência de blocos, cada um contendo informações sobre uma única tela. Para cada tela, o bloco relativo contém uma lista de outros blocos, cada um relativo a uma profundidade de cor específica que é suportada pela tela. Para cada profundidade suportada, esta lista contém uma lista de tipos visuais. Como resultado, cada tela está associada a uma série de profundidades possíveis, e cada profundidade de cada tela está associada a uma série de tipos visuais possíveis. Um determinado tipo visual pode ser usado para mais telas e para diferentes profundidades.

Para cada tipo visual, o pacote de aceitação contém seu identificador e os parâmetros reais que ele contém (classe visual, etc.) O cliente armazena esta informação, pois não pode solicitá-la posteriormente. Além disso, os clientes não podem alterar ou criar novos tipos visuais. Os pedidos de criação de uma nova janela incluem a profundidade e o identificador do tipo visual a utilizar para representar as cores desta janela.

Colormaps são usados ​​independentemente de o hardware que controla a tela (por exemplo, uma placa gráfica ) usar uma paleta , que é uma tabela que também é usada para representar cores. Os servidores usam mapas de cores mesmo se o hardware não estiver usando uma paleta. Sempre que o hardware usa paletas, apenas um número limitado de mapas de cores pode ser instalado. Em particular, um mapa de cores é instalado quando o hardware mostra as cores de acordo com ele. Um cliente pode solicitar que o servidor instale um mapa de cores. No entanto, isso pode exigir a desinstalação de outro mapa de cores: o efeito é que as janelas que usam o mapa de cores desinstalado não são mostradas com a cor correta, um efeito apelidado de cor intermitente ou tecnicolor . Esse problema pode ser resolvido usando mapas de cores padrão , que são mapas de cores com uma associação previsível entre valores de pixel e cores. Graças a esta propriedade, os mapas de cores padrão podem ser usados ​​por diferentes aplicativos.

A criação de mapas de cores é regulamentada pela convenção ICCCM . Os mapas de cores padrão são regulamentados pelo ICCCM e pela especificação Xlib .

Uma parte do sistema de cores X é o Sistema de gerenciamento de cores X (xcms). Este sistema foi introduzido com o X11R6 Release 5 em 1991. Este sistema consiste em vários recursos adicionais no xlib, encontrados na série de funções Xcms *. Este sistema define esquemas de cores independentes de dispositivo que podem ser convertidos em sistemas RGB dependentes de dispositivo. O sistema consiste nas funções xlib Xcms * e também na X Device Color Characterization Convention (XDCCC), que descreve como converter os vários sistemas de cores independentes do dispositivo em sistemas de cores RGB dependentes do dispositivo. Este sistema é compatível com CIEXYZ , xyY , CIELUV e CIELAB e também com os sistemas de cores TekHVC . [1] , [2]

Átomos

Os átomos são inteiros de 32 bits que representam strings . Os projetistas do protocolo introduziram os átomos porque eles representam strings em um tamanho curto e fixo: enquanto uma string pode ser arbitrariamente longa, um átomo é sempre um inteiro de 32 bits. A brevidade do átomo foi explorada ao obrigar seu uso nos tipos de pacotes que provavelmente serão enviados muitas vezes com as mesmas strings; isso resulta em um uso mais eficiente da rede. O tamanho fixo dos átomos foi explorado pela especificação de um tamanho fixo para eventos, a saber, 32 bytes: pacotes de tamanho fixo podem conter átomos, enquanto não podem conter cadeias longas.

Precisamente, os átomos são identificadores de strings armazenadas no servidor. Eles são semelhantes aos identificadores de recursos (Windows, Pixmaps, etc.), mas diferem deles de duas maneiras. Primeiro, os identificadores de átomos são escolhidos pelo servidor, não pelo cliente. Em outras palavras, quando um cliente solicita a criação de um novo átomo, ele apenas envia ao servidor a string a ser armazenada, não seu identificador; esse identificador é escolhido pelo servidor e enviado de volta como uma resposta ao cliente. A segunda diferença importante entre recursos e átomos é que os átomos não estão associados a clientes. Depois de criado, um átomo sobrevive até que o servidor seja encerrado ou reiniciado (este não é o comportamento padrão dos recursos).

Os átomos são identificadores e, portanto, únicos. No entanto, um átomo e um identificador de recurso podem coincidir. A string associada a um átomo é chamada de nome do átomo . O nome de um átomo não pode ser alterado após a criação, e dois átomos não podem ter o mesmo nome. Como resultado, o nome de um átomo é comumente usado para indicar o átomo: "o átomo ABCD " significa, mais precisamente, "o átomo cuja string associada é ABCD ." ou "o átomo cujo nome é ABCD ." Um cliente pode solicitar a criação de um novo átomo e pode solicitar o átomo (o identificador) de uma determinada string. Alguns átomos são predefinidos (criados pelo servidor com determinado identificador e string).

Os átomos são usados ​​para vários fins, principalmente relacionados à comunicação entre diferentes clientes conectados ao mesmo servidor. Em particular, eles são usados ​​em associação com as propriedades das janelas, que são descritas a seguir.

A lista de todos os átomos que residem em um servidor pode ser impressa usando o programa xlsatoms . Em particular, este programa imprime cada átomo (o identificador, isto é, um número) com seu nome (sua string associada).

Propriedades

Cada janela possui um conjunto predefinido de atributos e um conjunto de propriedades, todos armazenados no servidor e acessíveis aos clientes por meio de solicitações apropriadas. Atributos são dados sobre a janela, como tamanho, posição, cor de fundo, etc. Propriedades são partes arbitrárias de dados anexadas a uma janela. Ao contrário dos atributos, as propriedades não têm significado no nível do protocolo central do X Window. Um cliente pode armazenar dados arbitrários em uma propriedade de uma janela.

Uma propriedade é caracterizada por um nome, um tipo e um valor. Propriedades são semelhantes a variáveis em linguagens de programação imperativas , em que um cliente pode criar uma nova propriedade com um determinado nome e tipo e armazenar um valor nela. As propriedades estão associadas às janelas: duas propriedades com o mesmo nome podem existir em duas janelas diferentes com tipos e valores diferentes.

O nome, tipo e valor de uma propriedade são strings; mais precisamente, são átomos, ou seja, strings armazenadas no servidor e acessíveis aos clientes por meio de identificadores. Um aplicativo cliente pode acessar uma determinada propriedade usando o identificador do átomo que contém o nome da propriedade.

As propriedades são usadas principalmente para comunicação entre clientes. Por exemplo, a propriedade nomeada WM_NAME (a propriedade nomeada pelo átomo cuja string associada é "WM_NAME" ) é usada para armazenar o nome de janelas. Os gerenciadores de janela normalmente leem esta propriedade para exibir o nome das janelas em sua barra de título.

Alguns tipos de comunicação entre clientes usam propriedades da janela raiz. Por exemplo, de acordo com a especificação do gerenciador de janelas freedesktop , os gerenciadores de janela devem armazenar o identificador da janela atualmente ativa na propriedade chamada _NET_ACTIVE_WINDOW da janela raiz. Os recursos do X , que contêm parâmetros de programas, também são armazenados nas propriedades da janela raiz; dessa forma, todos os clientes podem acessá-los, mesmo se estiverem em computadores diferentes.

O xprop programa imprime as propriedades de uma determinada janela; xprop -root imprime o nome, tipo e valor de cada propriedade da janela raiz.

Mapeamentos

Image
Esta tecla sempre gera o mesmo código de acesso , mas os símbolos / , 7 e { estão associados a três diferentes keysyms .

No X Window System, cada chave física individual é associada a um número no intervalo de 8 a 255, chamado de código de chave . Um código de chave identifica apenas uma chave, não um caractere ou termo específico (por exemplo, "Page Up") entre os que podem estar impressos na chave. Cada um desses caracteres ou termos é identificado por um símbolo de tecla . Embora um código de tecla dependa apenas da tecla real que é pressionada, um símbolo de tecla pode depender, por exemplo, se a tecla Shift ou outro modificador também foi pressionado.

Quando uma tecla é pressionada ou liberada, o servidor envia eventos do tipo KeyPress ou KeyRelease para os clientes apropriados. Esses eventos contêm:

  1. o código da tecla pressionada
  2. o estado atual dos modificadores (Shift, Control, etc.) e botões do mouse
Image
Tradução de keycode para keysym.

O servidor, portanto, envia o código-chave e o estado do modificador sem tentar traduzi-los em um caractere específico. É responsabilidade do cliente fazer essa conversão. Por exemplo, um cliente pode receber um evento informando que uma determinada tecla foi pressionada enquanto o modificador Shift estava pressionado. Se esta chave normalmente geraria o caractere "a", o cliente (e não o servidor) associa este evento ao caractere "A".

Enquanto a tradução de keycodes para keysyms é feita pelo cliente, a tabela que representa esta associação é mantida pelo servidor. Armazenar esta tabela em um local centralizado torna-a acessível a todos os clientes. Os clientes típicos apenas solicitam esse mapeamento e o usam para decodificar o código-chave e o campo modificadores de um evento-chave em um keysym. No entanto, os clientes também podem alterar esse mapeamento à vontade.

Um modificador é uma tecla que, quando pressionada, altera a interpretação de outras teclas. Um modificador comum é a tecla Shift : quando a tecla que normalmente produz um "a" minúsculo é pressionada junto com Shift, produz um "A" maiúsculo. Outros modificadores comuns são "Control", "Alt" e "Meta".

O servidor X funciona com no máximo oito modificadores. No entanto, cada modificador pode ser associado a mais de uma tecla. Isso é necessário porque muitos teclados têm teclas duplicadas para alguns modificadores. Por exemplo, muitos teclados têm duas teclas "Shift" (uma à esquerda e outra à direita). Essas duas teclas produzem dois códigos de tecla diferentes quando pressionadas, mas o servidor X associa ambos ao modificador "Shift".

Para cada um dos oito modificadores, o servidor X mantém uma lista dos códigos-chave que ele considera ser esse modificador. Por exemplo, se a lista do primeiro modificador (o modificador "Shift") contém o código de 0x37 tecla, então a tecla que produz o código de 0x37 tecla é considerada uma tecla de deslocamento pelo servidor X.

As listas de mapeamentos de modificadores são mantidas pelo servidor X, mas podem ser alteradas por cada cliente. Por exemplo, um cliente pode solicitar que a " tecla F1 " seja adicionada à lista de modificadores "Shift". Deste ponto em diante, esta tecla se comporta como outro modificador de deslocamento. No entanto, o código de tecla correspondente a F1 ainda é gerado quando esta tecla é pressionada. Como resultado, F1 opera como antes (por exemplo, uma janela de ajuda pode ser aberta quando é pressionada), mas também funciona como a tecla shift (pressionar "a" em um editor de texto enquanto F1 está pressionado adiciona "A" ao texto atual).

O servidor X mantém e usa um mapeamento de modificador para os botões do mouse. No entanto, os botões só podem ser permutados . Isso é útil principalmente para trocar o botão da extrema esquerda e da extrema direita para usuários canhotos .

O xmodmap programa mostra e altera os mapeamentos de tecla, modificador e botão do mouse.

Agarra

Uma captura é uma condição na qual todos os eventos de teclado ou mouse são enviados a um único cliente. Um cliente pode solicitar uma captura do teclado, do mouse ou de ambos: se a solicitação for atendida pelo servidor, todos os eventos de teclado / mouse são enviados para o cliente de captura até que a captura seja liberada. Os outros clientes não receberão esses eventos.

Ao solicitar uma captura, um cliente especifica uma janela de captura : todos os eventos são enviados para o cliente de captura como se fossem relativos à janela de captura. No entanto, os outros clientes não recebem eventos, mesmo que os tenham selecionado na janela de captura. Existem dois tipos de captura:

  • ativo: a captura ocorre imediatamente
  • passivo: a captura ocorre apenas quando uma tecla ou botão do mouse especificado anteriormente é pressionado e termina quando é liberado
Image
Se o ponteiro ou o teclado estiverem congelados, os eventos que eles geram são bloqueados em uma fila. Se eles forem capturados, seus eventos serão redirecionados para o cliente que os está capturando, em vez da janela que normalmente os recebe. Os eventos de ponteiro podem ser descartados dependendo de uma máscara de evento.

Um cliente pode estabelecer uma pegada sobre o teclado, o ponteiro ou ambos. Uma solicitação de captura pode incluir uma solicitação de congelamento do teclado ou do ponteiro. A diferença entre agarrar e congelar é que agarrar muda o destinatário dos eventos, enquanto o congelamento interrompe totalmente sua entrega. Quando um dispositivo é congelado, os eventos que ele gera são armazenados em uma fila para serem entregues normalmente quando o congelamento terminar.

Para eventos de ponteiro, um parâmetro adicional afeta a entrega de eventos: uma máscara de evento, que especifica quais tipos de eventos devem ser entregues e quais devem ser descartados.

As solicitações de captura incluem um campo para especificar o que acontece com os eventos que seriam enviados ao cliente de captura, mesmo se ele não tivesse estabelecido a captura. Em particular, o cliente pode solicitar que sejam enviados normalmente ou de acordo com a captura. Essas duas condições não são iguais ao que podem parecer. Por exemplo, um cliente que normalmente receberia os eventos do teclado em uma primeira janela pode solicitar que o teclado seja capturado por uma segunda janela. Os eventos que normalmente seriam enviados para a primeira janela podem ou não ser redirecionados para a janela de captura, dependendo do parâmetro na solicitação de captura.

Um cliente também pode solicitar a captura de todo o servidor. Nesse caso, nenhuma solicitação será processada pelo servidor, exceto as que vêm do cliente de download.

De outros

Existem outras solicitações e eventos no protocolo principal. O primeiro tipo de solicitação é relativo ao relacionamento pai entre as janelas: um cliente pode solicitar a alteração do pai de uma janela ou pode solicitar informações sobre a paternidade das janelas. Outras solicitações são relativas à seleção , que, no entanto, é principalmente regida por outros protocolos. Outras solicitações são sobre o foco de entrada e a forma do ponteiro . Um cliente também pode solicitar que o proprietário de um recurso (janela, pixmap, etc.) seja eliminado, o que faz com que o servidor encerre a conexão com ele. Finalmente, um cliente pode enviar uma solicitação sem operação para o servidor.

Extensões

Image
A extensão da forma permite que o oclock crie uma janela redonda.

O protocolo central do X Window foi projetado para ser extensível. O protocolo principal especifica um mecanismo para consultar as extensões disponíveis e como as solicitações de extensão, eventos e pacotes de erros são feitos.

Em particular, um cliente pode solicitar a lista de todas as extensões disponíveis para dados relativos a uma extensão específica. Os pacotes de extensões são semelhantes aos pacotes do protocolo principal. O protocolo principal especifica que os pacotes de solicitação, evento e erro contêm um número inteiro indicando seu tipo (por exemplo, a solicitação para criar uma nova janela é numerada 1). Uma série desses inteiros são reservados para extensões.

Autorização

Quando o cliente estabelece inicialmente uma conexão com o servidor, o servidor pode responder aceitando a conexão, recusando-a ou solicitando autenticação . Uma solicitação de autenticação contém o nome do método de autenticação a ser usado. O protocolo principal não especifica o processo de autenticação, que depende do tipo de autenticação usado, exceto que termina com o servidor enviando um pacote de aceitação ou recusa.

Durante a interação regular entre um cliente e um servidor, as únicas solicitações relacionadas à autenticação são sobre o método de acesso baseado em host . Em particular, um cliente pode solicitar que esse método seja ativado e pode solicitar a leitura e a alteração da lista de hosts ( clientes ) que estão autorizados a se conectar. Os aplicativos típicos não usam essas solicitações; eles são usados ​​pelo xhost programa para fornecer a um usuário ou script acesso à lista de acesso do host. O método de acesso baseado em host é considerado inseguro.

Xlib e outras bibliotecas cliente

A maioria dos programas cliente se comunica com o servidor por meio da biblioteca cliente Xlib . Em particular, a maioria dos clientes usa bibliotecas como Xaw , Motif , GTK + ou Qt que, por sua vez, usam Xlib para interagir com o servidor. O uso de Xlib tem os seguintes efeitos:

  1. O Xlib torna o cliente síncrono com relação a respostas e eventos:
    1. as funções Xlib que enviam solicitações bloqueiam até que as respostas apropriadas, se alguma for esperada, sejam recebidas; em outras palavras, um cliente X Window que não usa Xlib pode enviar uma solicitação ao servidor e depois fazer outras operações enquanto espera pela resposta, mas um cliente que usa Xlib só pode chamar uma função Xlib que envia a solicitação e espera pela resposta, bloqueando assim o cliente enquanto espera pela resposta (a menos que o cliente inicie uma nova thread antes de chamar a função);
    2. enquanto o servidor envia eventos de forma assíncrona , o Xlib armazena em uma fila os eventos recebidos pelo cliente ; o programa cliente só pode acessá-los chamando explicitamente as funções da biblioteca X11; em outras palavras, o cliente é forçado a bloquear ou esperar ocupado se estiver esperando um evento.
  2. O Xlib não envia solicitações ao servidor imediatamente, mas as armazena em uma fila, chamada de buffer de saída ; as solicitações no buffer de saída são realmente enviadas quando:
    1. o programa solicita explicitamente chamando uma função de biblioteca como XFlush ;
    2. o programa chama uma função que fornece como resultado algo que envolve uma resposta do servidor, como XGetWindowAttributes ;
    3. o programa pede um evento na fila de eventos (por exemplo, chamando XNextEvent ) e os blocos de chamada (por exemplo, XNextEvent blocos se a fila estiver vazia).

Bibliotecas de nível superior, como Xt (que por sua vez é usado por Xaw e Motif ) permitem que o programa cliente especifique as funções de retorno de chamada associadas a alguns eventos; a biblioteca se encarrega de pesquisar a fila de eventos e chamar a função apropriada quando necessário; alguns eventos, como aqueles que indicam a necessidade de redesenhar uma janela, são tratados internamente pelo Xt.

Bibliotecas de nível inferior, como XCB , fornecem acesso assíncrono ao protocolo, permitindo melhor ocultação da latência.

Peças não especificadas

O protocolo central do X Window System não impõe comunicação entre clientes e não especifica como as janelas são usadas para formar os elementos visuais comuns nas interfaces gráficas do usuário ( botões , menus , etc.). Os elementos da interface gráfica com o usuário são definidos por bibliotecas cliente realizando kits de ferramentas de widget . A comunicação entre clientes é coberta por outros padrões, como as especificações ICCCM e freedesktop .

A comunicação entre clientes é relevante para seleções, buffers de corte e arrastar e soltar , que são os métodos usados ​​por um usuário para transferir dados de uma janela para outra. Como as janelas podem ser controladas por diferentes programas, é necessário um protocolo para a troca desses dados. A comunicação entre clientes também é relevante para os gerenciadores de janelas X , que são programas que controlam a aparência das janelas e a aparência geral da interface gráfica do usuário. Outra questão em que a comunicação entre clientes é até certo ponto relevante é a do gerenciamento de sessões .

Como uma sessão de usuário é iniciada é outro problema que não é coberto pelo protocolo principal. Normalmente, isso é feito automaticamente pelo gerenciador de tela X . O usuário também pode iniciar uma sessão manualmente executando os programas xinit ou startx .

Veja também

Referências

links externos