O sistema X Window, também conhecido como X11, é um sistema de janelas amplamente utilizado em sistemas operacionais baseados em Unix, como o Linux. A criação de janelas em um ambiente X11 é feita usando a API Xlib, que permite que os programas se comuniquem com o servidor X e gerenciem as janelas e outros objetos gráficos.
Neste artigo, vamos mostrar um exemplo mínimo de código em C para criar uma janela usando a API Xlib. Este código vai criar uma janela simples que pode ser redimensionada e movida pelo usuário.
Antes de começarmos, é importante notar que o código que vamos mostrar aqui é apenas um exemplo mínimo e não inclui muitas das funcionalidades que seriam necessárias em uma aplicação real. Além disso, o código foi testado em um sistema Linux e pode precisar de adaptação em outros sistemas operacionais.
Vamos começar criando um arquivo chamado “main.c” e incluindo os seguintes cabeçalhos:
#include <X11/Xlib.h> #include <stdio.h> #include <stdlib.h>
O cabeçalho “X11/Xlib.h” é o principal cabeçalho da API Xlib e fornece as definições das funções e tipos de dados necessários para criar uma janela. O cabeçalho “stdio.h” fornece as definições para funções de entrada e saída padrão, enquanto “stdlib.h” fornece definições para funções de alocação de memória e outras funções de propósito geral.
Em seguida, precisamos definir algumas constantes que serão usadas pelo nosso programa:
#define BORDER_WIDTH 2 #define WINDOW_TITLE "Minha janela X11" #define WINDOW_WIDTH 400 #define WINDOW_HEIGHT 300
A constante “BORDER_WIDTH” define a largura da borda da janela em pixels, enquanto “WINDOW_TITLE” define o título da janela. “WINDOW_WIDTH” e “WINDOW_HEIGHT” definem a largura e altura da janela em pixels, respectivamente.
Agora podemos definir a função principal do programa:
int main() { Display *display; Window window; int screen; XEvent event; display = XOpenDisplay(NULL); if(display == NULL) { fprintf(stderr, "Não foi possível abrir o display\n"); exit(1); } screen = DefaultScreen(display); window = XCreateSimpleWindow(display, RootWindow(display, screen), 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT, BORDER_WIDTH, BlackPixel(display, screen), WhitePixel(display, screen)); XStoreName(display, window, WINDOW_TITLE); XSelectInput(display, window, ExposureMask | KeyPressMask | StructureNotifyMask); XMapWindow(display, window); while(1) { XNextEvent(display, &event); switch(event.type) { case Expose: break; case ConfigureNotify: XResizeWindow(display, window, event.xconfigure.width, event.xconfigure.height); break; case KeyPress: XCloseDisplay(display); exit(0); } } return 0; }
Vamos agora analisar este código em detalhes. A primeira coisa que fazemos é declarar algumas variáveis, incluindo um ponteiro para a estrutura “Display”, que representa a conexão com o servidor X, um identificador de janela, um número de tela e uma estrutura XEvent, que será usada para armazenar eventos do servidor X.
Em seguida, usamos a função XOpenDisplay para abrir uma conexão com o servidor X. Se essa função retornar NULL, significa que não foi possível abrir o display e o programa é encerrado. Caso contrário, obtemos o número de tela padrão usando a função DefaultScreen e prosseguimos criando a janela usando a função XCreateSimpleWindow.
A função XCreateSimpleWindow cria uma janela com a posição (0,0) e as dimensões especificadas em WINDOW_WIDTH e WINDOW_HEIGHT, com uma borda de largura BORDER_WIDTH e as cores preto e branco para o pixel de borda e fundo, respectivamente. Também é especificado o ID da janela raiz usando a função RootWindow.
Em seguida, usamos a função XStoreName para definir o título da janela e a função XSelectInput para especificar quais tipos de eventos a janela deve receber. No nosso caso, estamos interessados nos eventos de exposição (Exposure), teclas pressionadas (KeyPress) e mudanças na estrutura da janela (ConfigureNotify).
Depois disso, chamamos a função XMapWindow para exibir a janela na tela. Em seguida, entramos em um loop infinito que espera por eventos do servidor X usando a função XNextEvent e os processa de acordo com o tipo de evento.
Se um evento de exposição ocorrer, não precisamos fazer nada, então o código apenas pula para o próximo evento. Se ocorrer um evento de mudança de configuração da janela, usamos a função XResizeWindow para redimensionar a janela de acordo com as novas dimensões especificadas no evento. Se um evento de tecla pressionada ocorrer, usamos a função XCloseDisplay para fechar a conexão com o servidor X e sair do programa.
Por fim, o programa retorna 0 para indicar que a execução foi concluída com sucesso.
Em resumo, este exemplo de código cria uma janela simples usando a API Xlib, que pode ser redimensionada e movida pelo usuário. Embora seja um exemplo mínimo e não inclua muitas das funcionalidades que seriam necessárias em uma aplicação real, deve ajudar a entender como a API Xlib funciona e como criar janelas em um ambiente X11.