: Программирование в среде X Window на основе библиотеки Xlib :

С о д е р ж а н и е

Введение

I. Базовые понятия X Window
Характеристики X-окна
Менеджер окон
Свойства и атомы
Первый пример
События
Атрибуты окна
Операции над окнами

II. Текст и графика
Графический контекст
Характеристики графического контекста
Вывод текста, работа с шрифтами
Использование цвета
Битовые и пиксельные карты
Изменяем курсор мыши

III. Работа с внешними устройствами
Клавиатура
Мышь

IV. Ресурсы программ
Формат файла ресурсов
Доступ к ресурсам программ

V. Взаимодействие клиентов
Механизм свойств
Работаем с менеджером окон

VI. Дополнительная информация

VII. Литература

Работаем с менеджером окон

Менеджер окон - это специальный клиент, в задачи которого входит интерактивное перемещение окон по экрану, изменение их размеров, минимизация (превращение в пиктограмму) и многое другое. Чтобы облегчить менеджеру его нелегкую жизнь, программам рекомендуется при инициализации сообщить о себе определенную информацию. Передается она через предопределенные свойства, которые известны менеджеру и могут быть им прочитаны. Некоторые из свойств (так называемые стандартные) задавать обязательно. Все остальное определяется по усмотрению программы. Наиболее простой способ задать стандартные свойства - обратиться к функциям XSetStandardProperties() или XSetWMProperties().

Свойства, создаваемые для менеджера окон программами, а также функции для работы с ними.

В ряде случаев стоит сообщить оконному менеджеру о том, какой размер окна нужен, и в каких пределах будут изменяться его размеры. Например, для терминальной программы (такой, как xterm), хотелось бы, чтобы окно всегда содержало полное количество строк и столбцов. В других случаях нежелательно давать возможность менять размер окна (например, в диалоговых окнах). Эти пожелания можно передать оконному менеджеру, хотя ничто не помешает ему их проигнорировать. Для этого необходимо создать структуру данных, заполнить ее необходимыми данными и затем использовать функцию XSetWMNormalHints():

/* указатель на структуру рекомендаций о размерах. */
XSizeHints* size_hints = XAllocSizeHints();
if (!size_hints) {
  fprintf(stderr, "XAllocSizeHints - нет памяти\n");
  exit(1);
}

/* Инициализация структуры */
/* Вначале укажем, что передаются пожелания о размерах: */
/* установим минимальный и начальный размеры. */
size_hints->flags = PSize | PMinSize;
/* Затем указываем требуемые границы.              */
/*создаем окно минимальным размером 300x200 пикселей */
/* и устанавливаем начальный размер в 400x250.          */
size_hints->min_width = 300;
size_hints->min_height = 200;
size_hints->base_width = 400;
size_hints->base_height = 250;

/* Передаем пожелания о размерах оконному менеджеру. */
XSetWMNormalHints(display, win, size_hints);

/* В конце необходимо освободить память из-под структуры. */
XFree(size_hints);

Дополнительные параметры окна: способ работы с клавиатурой, вид и положение пиктограммы. Идентифицируется атомом XA_WM_HINTS и имеет тип XA_WM_HINTS. Данные свойства - структура типа XWMHints. Для задания свойства используется функция XSetWMHints(). Структура типа XWMHints, передаваемая функции XSetWMHints(), должна быть подготовлена с помощью XAllocWMHints():

XWMHints* win_hints = XAllocWMHints();
if (!win_hints) {
  fprintf(stderr, "XAllocWMHints - нет памяти\n");
  exit(1);
}

/* установим пожелания о состоянии окна, позиции его иконки */
/* и ее виде                        */
win_hints->flags = StateHint | IconPositionHint | IconPixmapHint;

/* Определим битовое изображение в формате Х - */
/* оно может быть создано программой xpaint  */
#define icon_bitmap_width 20
#define icon_bitmap_height 20
static char icon_bitmap_bits[] = {
 0x60, 0x00, 0x01, 0xb0, 0x00, 0x07, 0x0c, 0x03, 0x00, 0x04, 0x04, 0x00,
 0xc2, 0x18, 0x00, 0x03, 0x30, 0x00, 0x01, 0x60, 0x00, 0xf1, 0xdf, 0x00,
 0xc1, 0xf0, 0x01, 0x82, 0x01, 0x00, 0x02, 0x03, 0x00, 0x02, 0x0c, 0x00,
 0x02, 0x38, 0x00, 0x04, 0x60, 0x00, 0x04, 0xe0, 0x00, 0x04, 0x38, 0x00,
 0x84, 0x06, 0x00, 0x14, 0x14, 0x00, 0x0c, 0x34, 0x00, 0x00, 0x00, 0x00
};

/* Загрузим заданное битовое изображение */
/* и создадим из него пиксельную карту Х. */
Pixmap icon_pixmap = XCreateBitmapFromData(display,
                      win,
                      icon_bitmap_bits,
                      icon_bitmap_width,
                      icon_bitmap_height);
if (!icon_pixmap) {
 fprintf(stderr, "XCreateBitmapFromData: ошибка создания pixmap\n");
 exit(1);
}

/* Затем детализируем желаемые изменения.             */
/* в нашем случае - сворачиваем окно, определяем его иконку    */
/* и устанавливаем позицию иконки в левом верхнем углу экрана.   */
win_hints->initial_state = IconicState;
win_hints->icon_pixmap = icon_pixmap;
win_hints->icon_x = 0;
win_hints->icon_y = 0;

/* Передаем пожелания оконному менеджеру. */
XSetWMHints(display, win, win_hints);

/* В конце необходимо освободить память из-под структуры. */
XFree(win_hints);

Получить данные свойства можно с помощью XGetWMHints().

Атрибут, характеризующий "временное" окно. Идентифицируется атомом XA_WM_TRANSIENT_FOR и имеет тип XA_STRING. Свойство задается для окон, появляющихся на экране для выполнения вспомогательных функций (диалоги, меню). Такие объекты рассматриваются менеджером по особому. Например, он может не добавлять к окну заголовок и рамку. Данные свойства - идентификатор окна родительского по отношению к данному. Задается свойство с помощью функции XSetTransientForHint().

Имена программы и ее класса, идентифицируется атомом XA_WM_CLASS и имеет тип XA_STRING. Данные свойства - структура типа XClassHints. Задается свойство с помощью функции XSetClassHint() и может быть получено с помощью XGetClassHint().

Если окно (окна) программы имеют собственную цветовую палитру, то приложение должно соответствующим образом задать для него атрибут colormap. Программа заносит идентификатор окна (идентификаторы окон) в список, ассоциированный со свойством, имя которого WM_COLORMAP_WINDOWS. Делается это функцией XSetWMColormapWindows(). Получить список, уже находящийся в свойстве, можно, обратившись к XGetWMColormapWindows().

Когда окно открыто, пользователь посредством менеджера совершает над ним разные действия. Программе может быть желательно перехватывать некоторые из них. Так, например, если окно представляет собой редактор текста, и пользователь пытается его закрыть, то разумно спросить у сидящего за компьютером человека, а не желает ли он предварительно сохранить результаты редакции. Начиная с X11R4 системой предусматривается свойство с именем WM_PROTOCOLS. Оно содержит список атомов, и каждый из них идентифицирует свойство, связанное с действиями, о которых надо оповещать программу. Эти свойства следующие:

Свойство WM_PROTOCOLS задается функцией XSetWMProtocols() и может быть получено с помощью XGetWMProtocols().

Приведем фрагмент программы, задающей свойство WM_PROTOCOLS и производящей соответствующую обработку событий.

. . . . . . .
Display		*display;
int		screenNumber;
GC		gc;
XEvent		report;
Window		window;
Atom		pnprotocol[2];
Atom		wmprotocols;

/*
 *Устанавливаем связь с сервером, получаем номер экрана,
 *создаем окно, выбираем события, обрабатываемые программой
 */
. . . . . . .

/* Задаем свойство WM_PROTOCOLS */

pnprotocol [0] = XInternAtom (display, "WM_TAKE_FOCUS", True);

pnprotocol [1] = XInternAtom (display, "WM_SAVE_YOURSELF", True);

wmprotocols = XInternAtom (display, "WM_PROTOCOLS", True);

XSetWMProtocols (display, window, pnprotocol, 2);

/* Покажем окно */

XMapWindow (display, window);

/* Цикл обработки событий */

while (1) {
   XNextEvent (display, &report);

switch (report.type) {
  . . . . . .
  case ClientMessage :
  if (report.xclient.message_type == wmprotocols)
  {
    if (report.xclient.data.l[0] == pnprotocol[0])
     puts ("Receiving the input focus.\n");
    else
     if (report.xclient.data.l[0] == pnprotocol[1])
     {
	XCloseDisplay (display);
	exit (0);
     } 
   }
   break;
   . . . . . . .
 }
}
. . . . . . .

Заказывается реакция на два события: получение фокуса ввода (WM_TAKE_FOCUS) и завершение программы (WM_SAVE_YOURSELF). Когда сервер посылает событие первого типа, задача печатает соответствующее сообщение на устройства вывода. При приходе события второго типа, программа закрывает связь с сервером и завершается.

<<< Содержание >>>