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

С о д е р ж а н и е

Введение

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

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

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

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

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

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

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

Операции над окнами

Рассмотрим способы манипуляций окнами можно не только с помощью атрибутов: Xlib предоставляет набор функций для изменения их размеров, перемещения на экране и в стеке окон, сворачивания и т.п.

Первая пара операций, которые можно применить к окну - отображение или скрытие. Отображение окна заставляют окно появиться на экране, скрытие приводит к удалению с экрана (хотя логическое окно в памяти все еще существует). Например, если в вашей программе есть диалоговое окно, вместо создания его каждый раз по запросу пользователя, мы можем создать окно один раз в скрытом режиме и, когда пользователь запросит открыть диалог, просто отобразить окно на экране. Когда пользователь нажимает "OK" или "Cancel", окно скрывается. Это значительно быстрее создания и уничтожения окна, однако стоит ресурсов, как на стороне клиента, так и на стороне X сервера.

Отображение окна может быть выполнено с помощью XMapWindow(), скрытие - с помощью XUnmapWindow(). Функция отображения заставит событие Expose послаться программе, если только окно полностью не закрыто другими окнами.

Другое действие, которое можно выполнить над окнами - переместить их в другую позиции. Это может быть выполнено функцией XMoveWindow(), которая принимает новые координаты окна. Имейте в виду, что после перемещения окно может быть частично скрытым другими окнами (или наоборот, открыто ими), и таким образом, может быть сгенерировано сообщение Expose.

Изменить размер окна можно с помощью функции XResizeWindow(). Мы можем также объединить перемещение и изменение размеров, используя одну функцию XMoveResizeWindow().

Все приведенные выше функции изменяли свойства одного окна. Существует ряд свойств, связанных с данным окном и другими окнами. Одно из них - порядок засылки в стек: порядок, в котором окна располагаются друг над другом. Говорят, что окно переднего плана находится на верхе стека, а окно заднего плана - на дне стека. Перемещение окна на вершину стека осуществляет функция XRaiseWindow(), перемещение окна на дно стека - функция XLowerWindow().

С помощью функции XIconifyWindow() окно может быть свернуто, а с помощью XMapWindow() - восстановлено. Для того, чтобы понять, почему для XIconifyWindow() нет обратной функции, необходимо заметить, что, когда окно сворачивается, на самом деле оно скрывается, а вместо него отображается окно иконки. Таким образом, чтобы восстановить исходное окно, нужно просто отобразить его снова. Иконка является на самом деле другим окном, которое просто тесно связано сильно с нашим нормальным окном - это не другое состояние нашего окна.

Следующий пример демонстрирует использование операций над окнами:

#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

Window create_simple_window(Display* display, int width, int height, int x, int y)
{
 int scr_number = DefaultScreen(display);
 int win_border_width = 2;
 Window window;

 window = XCreateSimpleWindow(display, RootWindow(display, scr_number),
              x, y, width, height, window_border_width,
              BlackPixel(display, scr_number),
              WhitePixel(display, scr_number));

 XMapWindow(display, window);
 XFlush(display);

 return window;
}


int main(int argc, char* argv[])
{
 Display* display; /* указатель на структуру дисплея Х */
 int scr_number; /* количество экранов для размещения окон */
 Window window; /* дескриптор создаваемого окна */
 unsigned int display_width,
        display_height; /* высота и ширина Х дисплея */
 unsigned int window_width,
        window_height; /* высота и ширина нового окна */
 char *display_name = getenv("DISPLAY"); /* имя Х дисплея */

 /* устанавливаем соединение с Х сервером */
 display = XOpenDisplay(display_name);
 if (display == NULL) {
  fprintf(stderr, "%s: не могу соединиться с Х сервером '%s'\n",
      argv[0], display_name);
  exit(1);
 }

 /* получаем геометрию экрана по умолчанию для нашего дисплея */
 scr_number = DefaultScreen(display);
 display_width = DisplayWidth(display, scr_number);
 display_height = DisplayHeight(display, scr_number);

 /* создаем новое окно */
 window_width = (display_width / 6);
 window_height = (display_height / 6);
 /* печать в стандартный вывод */
 printf("ширина окна - '%d'; высота - '%d'\n", window_width, window_height);

 /* создаем простое окно как прямой потомок корневого окна экрана,  */
 /* используя черный и белый цвета в качестве основного и фонового, и*/
 /* размещая новое окно в верхнем левом углу по заданным координатам */
 window = create_simple_Window(display, window_width, window_height, 0, 0);

 XFlush(display);

 /* отдохнем после трудов праведных */
 sleep(3);

 /* пример изменения размеров окна */
 {
  int i;

  /* в цикле уменьшаем окно */
  for (i=0; i<40; i++) {
   window_width -= 3;
   window_height -= 3;
   XResizeWindow(display, window, window_width, window_height);
   XFlush(display);
   usleep(20000);
  }

  /* в цикле увеличиваем окно */
  for (i=0; i<40; i++) {
   window_width += 3;
   window_height += 3;
   XResizeWindow(display, window, window_width, window_height);
   XFlush(display);
   usleep(20000);
  }
 }

 sleep(1);

 /* пример перемещения окна */
 {
  int i;
  XWindowAttributes window_attr;
  int x, y;
  int scr_x, scr_y;
  Window child_window;
  /* переменная для хранения дескриптора родительского окна */
  Window parent_window;

  /* вначале получаем текущие атрибуты окна */
  XGetWindowAttributes(display, window, &window_attr);

  x = window_attr.x;
  y = window_attr.y;

  /* затем находим окно родителя */
  {
   /* эта переменная будет хранить дескриптор корневого окна */
   /* экрана, на котором отображено наше окно */
   Window root_window;
   /* эта переменная будет хранить массив дескрипторов */
   /* дочерних окон нашего окна, */
   Window* child_win;
   /* а эта - их количество */
   int num_child_win;

   /* выполним запрос необходимых значений */
   XQueryTree(display, window,
         &root_window,
         &parent_window,
         &child_win, &num_child_win);

   /* мы должны освободить список дочерних дескрипторов, */
   /* так как он был динамически выделен XQueryTree()  */
   XFree(child_win);
  }

  /* Транслируем локальные координаты в экранные, используя  */
  /* корневое окно как окно, относительно которого выполняется */
  /* трансляция. Это работает потому, что корневое окно всегда */
  /*занимает весь экран, и его левый верхний угол совпадает  */
  /* с левым верхним углом экрана               */
  XTranslateCoordinates(display,
             parent_window, window_attr.root,
             x, y,
             &scr_x, &scr_y,
             &child_window);

  /* перемещаем окно влево */
  for (i=0; i<40; i++) {
   scr_x -= 3;
   XMoveWindow(display, window, scr_x, scr_y);
   XFlush(display);
   usleep(10000);
  }

  /* перемещаем окно вправо */
  for (i=0; i<40; i++) {
   scr_x += 3;
   XMoveWindow(display, window, scr_x, scr_y);
   XFlush(display);
   usleep(10000);
  }
}

 sleep(1);

 /* пример сворачивания и восстановления окна */
 {
  /* сворачиваем окно */
  XIconifyWindow(display, window, DefaultScreen(display));
  XFlush(display);
  sleep(2);
  /* восстанавливаем окно */
  XMapWindow(display, window);
  XFlush(display);
  sleep(2);
 }

 XFlush(display);

 /* короткая передышка */
 sleep(2);

 /* закрываем соединение с Х сервером */
 XCloseDisplay(display);
 return 0;
}

Пример программы example3.c

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