Маска выбираемых событий может составляться с помощью побитового "ИЛИ" из таких значений:
• 0 - не ожидать никаких событий
• KeyPressMask - ожидать событие нажатия клавиши
• KeyReleaseMask - ожидать событие отпускания клавиши
• ButtonPressMask - ожидать событие нажатия кнопки мыши
• ButtonReleaseMask - ожидать событие отпускания кнопки мыши
• EnterWindowMask - ожидать событие входа в окно
• LeaveWindowMask - ожидать событие выхода из окна
• PointerMotionMask - ожидать событие движения мышиного курсора
• PointerMotionHintMask - ожидать событие движения мышиного курсора с дополнительными указаниями
• Button1MotionMask - ожидать событие движения мышиного курсора при нажатой первой кнопке
• Button2MotionMask - ожидать событие движения мышиного курсора при нажатой второй кнопке
• Button3MotionMask - ожидать событие движения мышиного курсора при нажатой третьей кнопке
• ButtonMotionMask - ожидать событие движения мышиного курсора при любой нажатой кнопке
• ExposureMask - ожидать событие необходимости перерисовки окна
• VisibilityChangeMask - ожидать событие изменения видимости
• ResizeRedirectMask - ожидать событие изменения размеров окна
• FocusChangeMask - ожидать событие изменения фокуса ввода
Некоторые события посылаются окну независимо от того, выбраны они или нет. Это:
• MappingNotify - посылается, когда изменяется состояние клавиатуры (соответствие физических и логических кодов;
• ClientMessage - так идентифицируются события, посылаемые от клиента к клиенту с помощью процедуры XSendEvent();
• SelectionClear, SelectionNotify, SelectionRequest - эти события используются в стандартном механизме общения между программами, работающими в X;
• Expose, NoExpose - эти события могут посылаться, когда клиент пытается копировать содержимое одного окна в другое.
Частой ошибкой начинающих программистов является добавление кода для обработки нового события без добавления маски для этого события в XSelectInput(). Можно часам сидеть и отлаживать программу в недоумении, почему она не реагирует на отпускание кнопки, только из-за того, что для кнопок событие нажатия зарегистрировано, а событие отпускания - нет.
Программа получает события в своем основном цикле. Для этого можно использовать ряд процедур. Наиболее простая из них:
functionXNextEvent(prDisplay: PDisplay; prEvent: PXEvent): longint;
cdecl;
external;
Она "вынимает" из очереди событие, находящееся в ее "голове", сохраняет информацию о нем в переменной, на которую указывает параметр prEvent, и возвращается. При этом само событие удаляется из очереди. Функция XPeekEvent() также возвращает переданное сервером событие, но не удаляет его из очереди.
Процедура XPending() возвращает общее число событий в очереди программы.
Итак, если событие выбрано для окна, то оно будет передано ему на обработку. А если нет? В этом случае событие передается родителю окна. Если и тот не желает обращать внимание на данное событие, то оно отправляется дальше, вверх по иерархии окон, и так до тех пор, пока либо не будет найдено окно, выбравшее это событие, либо событие не потеряется.
Задача может влиять на этот процесс продвижения события по иерархии окон. Если программа включает флаг, соответствующий событию, в специальный атрибут окна, то оно, достигнув это окно, не будет передано родителю, а будет тут же "снято с повестки дня". Этот атрибут - do_not_propagate.
1.1.8 Атрибуты окна
Многие атрибуты окна задаются при его создании с помощью процедуры XCreateWindow() или XCreateSimpleWindow(). Впоследствии параметры можно изменить, обратившись к процедуре XChangeWindowAttributes().
Характеристики окна описываются структурами типа TXSetWindowAttributes и TXWindowAttributes. Получить их можно с помощью процедуры XGetWindowAttributes().
Все они делятся на две группы. В первую входят параметры, доступные "на чтение" и "на запись". Вторая группа представляет собой внутренние данные. Программа может прочитать их, но не может менять.
Сначала перечислим поля этих структур, которые относятся к "изменяемым" параметрам.
Фон окнаопределяется атрибутами background_pixmap и background_pixel. Первый из них задает картинку (карту пикселей), которая используется для заливки фона окна. При необходимости картина повторяется слева направо и сверху вниз. Если параметр background_pixmap равен None (задается по умолчанию), то он игнорируется. Если же при этом поле background_pixel не задано (установлено по умолчанию), то окно считается "прозрачным", в противном случае его фон заливается цветом background_pixel. Атрибуты background_pixmap и background_pixel могут также принимать значение ParentRelative. В этом случае характеристики фона заимствуются у родительского окна.
Вид края окнаопределяется полями border_pixmap и border_pixel. Первый атрибут определяет карту пикселей, используемую для заполнения края. Если он равен None, то край заполняется цветом border_pixel. Если же и поле border_pixel не задано, то для изображения края используются соответствующие характеристики родителя. То же самое происходит, если параметр border_pixmap равен CopyFromParent (взять у родителя). Последнее значение есть значение по умолчанию.
На
перерисовкуокна после изменения его размеров влияют атрибуты bit_gravity и win_gravity. Когда окно меняет размер, например, увеличивается или уменьшается, то, в принципе, нет необходимости перерисовывать все его содержимое. Часть окна остается неизменной. Правда, эта часть может поменять свое положение: переместиться вправо, влево, вверх или вниз. Поле bit_gravity говорит серверу, что делать с оставшейся частью изображения. Возможные значения параметра следующие:
• ForgetGravity - содержимое окна перерисовывается (считается значением по умолчанию);
• StaticGravity - остающаяся часть не должна менять положение по отношению к главному (корневому - root) окну сервера;
• NorthWestGravity - остающаяся часть смещается к левому верхнему углу;
• NorthGravity - остающаяся часть смещается к верху окна;
• NorthEastGravity - остающаяся часть смещается к правому верхнему углу;
• WestGravity - остающаяся часть смещается к левому краю окна;
• CenterGravity - остающаяся часть смещается к центру окна;
• EastGravity - остающаяся часть смещается к правому краю окна;
• SouthWestGravity - остающаяся часть смещается к левому нижнему углу;
• SouthGravity - остающаяся часть смещается к нижнему краю окна;
• SouthEastGravity - остающаяся часть смещается к правому нижнему углу.
Параметр win_gravity говорит о том, что делать с
подокнамиокна после изменения размеров последнего. Возможные значения параметра следующие (при перечислении используются следующие обозначения: H - изменение размеров окна по горизонтали, V - изменение размеров по вертикали, (H, V) - смещение подокна на H пикселей по горизонтали и на V пикселей по вертикали):
• UnmapGravity - подокна удаляются с экрана; окну посылается событие UnmapNotify, в ответ на которое оно может переместить свои подокна и показать их с помощью процедуры XMapSubWindow();
• StaticGravity - подокна остаются на месте по отношению к главному (корневому) окну сервера;
• NorthWestGravity - устанавливается по умолчанию; соответствует смещению (0, 0);
• NorthGravity - смещение (H/2, 0);
• NorthEastGravity - смещение (H, 0);
• WestGravity - смещение (0, V/2);
• CenterGravity - смещение (H/2, V/2);
• EastGravity - смещение (H, V/2);
• SouthWestGravity - смещение (0, V);
• SouthGravity - смещение (H/2, V);
• SouthEastGravity - смещение (H, V).
Автоматическое сохранение содержимого окна, когда его часть перекрывается другими окнами, или, когда окно удаляется с экрана, определяется параметрами backing_store, backing_planes и backing_pixel. Сохраненные данные могут использоваться для восстановления окна, что значительно быстрее, чем его перерисовка программой в ответ на событие Expose. Параметр backing_store имеет следующие возможные значения:
• NotUseful (устанавливается по умолчанию) - серверу не рекомендуется сохранять содержимое окна;
• WhenMapped - серверу рекомендуется спасти содержимое невидимых частей окна, когда окно показывается на экране;
• Always - серверу рекомендуется сохранить содержимое окна даже, если оно не показано на экране.
Сохранение изображений требует, как правило, довольно большого расхода памяти. Атрибуты backing_planes и backing_pixel призваны
уменьшить этот расход. Первый из указанных параметров говорит серверу, какие плоскости изображения надо сохранять; backing_pixel означает, какой цвет использовать при восстановлении изображения в тех плоскостях, которые не сохранялись. По умолчанию backing_planes - маска, состоящая из единиц, а backing_pixel равно 0.
Иногда при показе окна полезно
сохранить содержимое экрана под окном. Если окно невелико, и показывается ненадолго, то это позволяет экономить время, которое надо будет затратить на перерисовку экрана после того, как окно будет закрыто. Если атрибут save_under равен True, то сервер будет пытаться сохранить изображение под окном. Если же он равен False (по умолчанию), то сервер ничего не предпринимает.
Когда обрабатывает (или не обрабатывает) событие, последнее может быть
передано его родительскому окну. Атрибут do_not_propagate_mask (по умолчанию 0) говорит и о том, какие события не должны доходить до родителей.
Изменение размеров окна и его положения на экранеконтролируется атрибутом override_redirect. Если он равен False, то размер окна и его положение меняются с помощью менеджера окон. Если же он равен True, то окно само решает, где ему быть, и какую ширину и высоту иметь.
Цветовую гаммуокна задает параметр colormap. Значение по умолчанию - CopyFromParent, которое говорит, что окно использует палитру своего непосредственного родителя.
Теперь рассмотрим "неизменяемые" параметры окна. Строго говоря, атрибуты, о которых пойдет речь, нельзя назвать неизменяемыми. Некоторые из них могут меняться сервером или менеджером окон. Но для обычных программ-клиентов они действительно являются таковыми.
Положение окна и его размерысообщают поля x, y, width и height. Они дают координаты левого верхнего угла, ширину и высоту окна соответственно. Координаты измеряются в пикселях по отношению к родительскому окну.
Ширина края окнаопределяется параметром border_width.
Маска, говорящая о том,
какие события выбраны для передачи окнупородившим его клиентом, содержится в поле флагов your_event_mask. Значение параметра образуется комбинацией флагов, идентифицирующих события.
Информация о дисплее, на котором показано окно, содержится в структуре Visual, на которую показывает поле visual. Эти данные, как правило, не обрабатываются обычными программами-клиентами (заметим, что для получения информации о дисплее, в системе предусмотрена процедура XGetVisualInfo()).
Класс окнасообщает поле class. Возможные значения: InputOutput и InputOnly.
Число цветовых плоскостей дисплея(число бит-на-пиксел) помещается в поле depth.
На
информацию об экране, на котором помещается окно, указывает поле screen. Она, как правило, не используется обычными программами.
Идентификатор главного (корневого) окна экрана, на котором помещается окно, находится в поле root.
Если окно имеет палитру, и она в настоящее время активна, то поле map_installed равно True, в противном случае - False.
Видно в настоящее время окно на экранеили нет, сообщает атрибут map_state.
Маска всех событий, выбранных всеми программами для данного окна, содержится в атрибуте all_event_mask. Дело в том, что окно обрабатывается не только порождающим его клиентом, но, возможно, и другими приложениями, например, менеджером окон.
Мы рассказали о том, как получить атрибуты окна, и что они означают. Теперь рассмотрим, как их изменить. Для этого можно использовать несколько процедур X Window, основной из которых является XChangeWindowAttributes(), имеющая следующий прототип:
functionXChangeWindowAttributes(prDisplay: PDisplay;
nWnd: TWindow; nValueMask: cardinal;
prWinAttr: PXSetWindowAttributes): longint;
cdecl;
external;
Требуемые установки атрибутов передаются через аргумент prWinAttr. Он указывает на переменную типа TXSetWindowAttributes. Ее поля те же, что и соответствующие поля TXWindowAttributes. Разница заключается лишь в разных именах некоторых из них. Так, поле your_event_mask в TXWindowAttributes соответствует полю event_mask в TXSetWindowAttributes.
Структура TXSetWindowAttributes содержит дополнительное поле cursor. Оно определяет
вид курсора мыши, когда последний находится в окне. Если поле равно None (значение по умолчанию), то используется курсор родительского окна, в противном случае значением параметра должен быть идентификатор того или иного курсора.
Параметр nValueMask при вызове указанной процедуры представляет комбинацию флагов, говорящих о том, какие из полей переменной prWinAttr принимать во внимание.
В следующем примере приведен фрагмент кода, в котором изменяются параметры border_pixmap и win_gravity некоторого окна:
…
var
prDisplay: PDisplay;
prWnd: TWindow;
rWndAttr: TXSetWindowAttributes;
nValMask: cardinal;
const
nPixmap: TPixmap = 0;
…
nValMask:= CWBorderPixmap
orCWWinGravity;
rWndAttr.border_pixmap:= nPixmap;
rWndAttr.win_gravity:= StaticGravity;
…
XChangeWindowAttributes (prDisplay, prWnd, nValMask, @rWndAttr);
…
Отдельные атрибуты окна можно изменить более просто с помощью специальных процедур. Так, например, функция XSetWindowBackground() меняет фон окна, XSetWindowBorder() - его край.
1.1.9 Операции над окнами
Манипулировать окнами можно не только с помощью атрибутов: Xlib предоставляет набор функций для изменения их размеров, перемещения на экране и в стеке окон, сворачивания и т.п.
Первая пара операций, которые можно применить к окну -
отображение или скрытие. Отображение окна заставляют окно появиться на экране, скрытие приводит к удалению с экрана (хотя логическое окно в памяти все еще существует). Например, если в вашей программе есть диалоговое окно, вместо создания его каждый раз по запросу пользователя, мы можем создать окно один раз в скрытом режиме и, когда пользователь запросит открыть диалог, просто отобразить окно на экране. Когда пользователь нажимает "OK" или "Cancel", окно скрывается. Это значительно быстрее создания и уничтожения окна, однако стоит ресурсов, как на стороне клиента, так и на стороне X сервера.
Отображение окна может быть выполнено с помощью XMapWindow(), скрытие - с помощью XUnmapWindow(). Функция отображения заставит событие Expose послаться программе, если только окно полностью не закрыто другими окнами.
Другое действие, которое можно выполнить над окнами -
переместитьих в другую позицию. Это может быть выполнено функцией XMoveWindow(), которая принимает новые координаты окна. Имейте в виду, что после перемещения окно может быть частично скрытым другими окнами (или наоборот, открыто ими), и таким образом, может быть сгенерировано сообщение Expose.
Изменить размер окнаможно с помощью функции XResizeWindow(). Мы можем также объединить перемещение и изменение размеров, используя одну функцию XMoveResizeWindow().
Все приведенные выше функции изменяли свойства одного окна. Существует ряд свойств, связанных с данным окном и другими окнами. Одно из них -
порядок засылки в стек: порядок, в котором окна располагаются друг над другом. Говорят, что окно переднего плана находится на верхе стека, а окно заднего плана - на дне стека. Перемещение окна на вершину стека осуществляет функция XRaiseWindow(), перемещение окна на дно стека - функция XLowerWindow().
С помощью функции XIconifyWindow() окно может быть
свернуто, а с помощью XMapWindow() -
восстановлено. Для того, чтобы понять, почему для XIconifyWindow() нет обратной функции, необходимо заметить, что, когда окно сворачивается, на самом деле оно скрывается, а вместо него отображается окно иконки. Таким образом, чтобы восстановить исходное окно, нужно просто отобразить его снова. Иконка является на самом деле другим окном, которое просто тесно связано сильно с нашим нормальным окном - это не другое состояние нашего окна.
Следующий пример демонстрирует использование операций над окнами:
uses x,xlib,xutil,crt,dos;
(* create_simple_window - создает окно с белым фоном заданного размера.
Принимает в качестве параметров дисплей, размер окна (в пикселях) и положение окна (также в пикселях). Возвращает дескриптор окна.
Окно создается с черной рамкой шириной в 2 пикселя и автоматичсеки отображается после создания.*)
function create_simple_window(display: PDisplay;
width, height, x, y: integer): TWindow;
var
screen_num, win_border_width: integer;
win: TWindow;
begin
screen_num:= XDefaultScreen(display);
win_border_width:= 2;
(*
создаем простое окно как прямой потомок корневого окна экрана,
используя черный и белый цвета в качестве основного и фонового, и
размещая новое окно в верхнем левом углу по заданным координатам
*)
win:= XCreateSimpleWindow(display, XRootWindow(display, screen_num),
x, y, width, height, win_border_width,
XBlackPixel(display, screen_num),
XWhitePixel(display, screen_num));
(* Отображаем окно на экране. *)
XMapWindow(display, win);
(* Заставляем выполниться все запросы к Х серверу. *)
XFlush(display);
create_simple_window:=win;
end;
//void main(int argc, char* argv[])
var
display: PDisplay;
(* указатель на структуру дисплея Х *)
screen_num: integer;
(* количество экранов для размещения окон *)
win: TWindow;
(* дескриптор создаваемого окна *)
display_width, display_height: word;
(* высота и ширина Х дисплея *)
win_width, win_height: word;
(* высота и ширина нового окна *)
display_name: array [0…30] of Char;
name: string;
i: integer;
win_attr: TXWindowAttributes;
xx, y, scr_x, scr_y: integer;
child_win: TWindow;
(* переменная для хранения дескриптора родительского окна *)
parent_win: TWindow;
(* эта переменная будет хранить дескриптор корневого окна
экрана, на котором отображено наше окно *)
root_win: TWindow;
(* эта переменная будет хранить массив дескрипторов дочерних окон нашего окна, *)
child_windows: PWindow;
(* а эта - их количество *)
num_child_windows: integer;
begin
name:= getenv('DISPLAY');
(* имя Х дисплея *)
for i:=1 to byte(name[0]) do
display_name[i-1]:=name[i];
display_name[byte(name[0])]:=#0;
(* устанавливаем соединение с Х сервером *)
display:= XOpenDisplay(display_name);
if (display = NIL) then begin
writeln(paramstr(0),': не могу соединиться с Х сервером ',
display_name);
halt(1);
end;
(* получаем геометрию экрана по умолчанию для нашего дисплея *)
screen_num:= XDefaultScreen(display);
display_width:= XDisplayWidth(display, screen_num);
display_height:= XDisplayHeight(display, screen_num);
(* создаем новое окно в 1/9 площади экрана *)
win_width:= (display_width div 3);
win_height:= (display_height div 3);
(* отладочная печать в стандартный вывод *)
writeln('ширина окна - ', win_width, '; высота - ', win_height);
(* создаем простое окно как прямой потомок корневого окна экрана, используя черный и белый цвета в качестве основного и фонового, и размещая новое окно в верхнем левом углу по заданным координатам *)
win:= create_simple_window(display, win_width, win_height, 0, 0);
XFlush(display);
(* отдохнем после трудов праведных *)
delay(3000);
(* пример изменения размеров окна *)
begin
(* в цикле уменьшаем окно *)
for i:=0 to 39 do begin
dec(win_width,3);
dec(win_height,3);
XResizeWindow(display, win, win_width, win_height);
XFlush(display);
delay(20);
end;
(* в цикле увеличиваем окно *)
for i:=0 to 39 do begin
inc(win_width,3);
inc(win_height,3);
XResizeWindow(display, win, win_width, win_height);
XFlush(display);
delay(20);
end;
end;
delay(1000);
(* пример перемещения окна *)
begin
(* вначале получаем текущие атрибуты окна *)
XGetWindowAttributes(display, win, @win_attr);
xx:= win_attr.x;
y:= win_attr.y;
(* затем находим окно родителя *)
begin
(* выполним запрос необходимых значений *)
XQueryTree(display, win,
@root_win,
@parent_win,
@child_windows, @num_child_windows);
(* мы должны освободить список дочерних дескрипторов, так как он был динамически выделен XQueryTree() *)
XFree(child_windows);
end;
(* Транслируем локальные координаты в экранные, используя корневое окно как окно, относительно которого выполняется трансляция. Это работает потому, что корневое окно всегда занимает весь экран, и его левый верхний угол совпадает с левым верхним углом экрана *)
XTranslateCoordinates(display, parent_win, win_attr.root, xx, y, @scr_x, @scr_y, @child_win);
(* перемещаем окно влево *)
for i:=0 to 39 do begin
dec(scr_x,3);
XMoveWindow(display, win, scr_x, scr_y);
XFlush(display);
delay(20);
end;
(* перемещаем окно вниз *)
for i:=0 to 39 do begin
inc(scr_y,3);
XMoveWindow(display, win, scr_x, scr_y);
XFlush(display);
delay(20);
end;
(* перемещаем окно вправо *)
for i:=0 to 39 do begin
inc(scr_x,3);
XMoveWindow(display, win, scr_x, scr_y);
XFlush(display);
delay(20);
end;
(* перемещаем окно вверх *)
for i:=0 to 39 do begin
dec(scr_y,3);
XMoveWindow(display, win, scr_x, scr_y);
XFlush(display);
delay(20);
end;
end;
delay(1000);
(* пример сворачивания и восстановления окна *)
begin
(* сворачиваем окно *)
XIconifyWindow(display, win, XDefaultScreen(display));
XFlush(display);
delay(2000);
(* восстанавливаем окно *)
XMapWindow(display, win);
XFlush(display);
delay(2000);
end;
XFlush(display);
(* короткая передышка *)
delay(2000);
(* закрываем соединение с Х сервером *)
XCloseDisplay(display);
end.
1.1.10 Лабораторная работа #1 "Основные понятия Xlib"
1. Используя компилятор командной строки, выполните компиляцию примера из п. 1.1 и выполните полученную программу.
2. Настройте интегрированную среду Анюта для работы с кириллицей и выполните компиляцию в ней предыдущей программы.
3. На основе примера напишите программу, которая при нажатии клавиши мыши пишет сообщение Pressed, а при отпускании - Released.
4. Используя функции XFlush() / XSync() и delay(), напишите программу без цикла обработки сообщений, отображающую черное окно размером 100х100 пикселей в течение 5 секунд.
1.2 Текст и графика
В данном разделе описываются возможности, которые имеет программист для вывода текста и произвольных графических изображений. Особенностью X является то, что рисовать можно не только в окне, но и в специально подготовленной области памяти. Данная область называется картой пикселей и идентифицируется целым числом, имеющим тип TPixmap. Карта толщиной в один бит имеет специальное название -
битовая.
1.2.1 Графический контекст
Прежде чем начать работу с графикой, программа должна выделить себе специальную структуру данных и получить указатель на нее. Эта структура называется
графическим контекстом(Graphic Context (GC)). Указатель на GC используется в качестве одного из параметров при вызове "рисующих" функций X. Графический контекст содержит ряд атрибутов, влияющих на отображение объектов: текста, линий, фигур и др. Выделенный GC должен быть освобожден до завершения работы программы.
Графический контекст создается процедурой XCreateGC(), имеющей следующий прототип:
functionXCreateGC(prDisplay: PDisplay; nDrawable: TDrawable; nValueMask: cardinal; prValues: PXGCValues): TGC;
cdecl;
external;
Первый аргумент - это указатель на структуру типа TDisplay, который программа получает после вызова XOpenDisplay(); второй - идентификатор окна (или карты пикселей), в котором программа будет рисовать; третий - битовая маска, определяющая, какие атрибуты GC задаются; последний аргумент - структура типа TXGCValues, определяемая следующим образом:
TXGCValues = record
Xfunction: longint;
{Renamed function to Xfunction}
plane_mask: cardinal;
foreground: cardinal;
background: cardinal;
line_width: longint;
line_style: longint;
cap_style: longint;
join_style: longint;
fill_style: longint;
fill_rule: longint;
arc_mode: longint;
tile: TPixmap;
stipple: TPixmap;
ts_x_origin: longint;
ts_y_origin: longint;
font: TFont;
subwindow_mode: longint;
graphics_exposures: TBool;
clip_x_origin: longint;
clip_y_origin: longint;
clip_mask: TPixmap;
dash_offset: longint;
dashes: char;
end;
PXGCValues = ^TXGCValues;
Значения полей данной структуры будут объяснены ниже. Каждому из них соответствует бит в маске, которая передается в качестве третьего параметра при вызове процедуры XCreateGC(). Эти биты обозначаются символическими константами, определенными в модуле X. Если бит установлен, то значение соответствующего атрибута должно быть взято из переданной функции XCreateGC() структуры TXGCValues. Если бит сброшен, то атрибут принимает значение по умолчанию.
Следующий пример показывает процесс создания графического контекста, в котором устанавливаются два атрибута: цвет фона и цвет переднего плана.
…
var
prGC: TGC;
rValues: TXGCValues;
prDisplay: PDisplay;
nScreenNum: integer;
…
rValues.foreground:= XBlackPixel (prDisplay, nScreenNum);
rValues.background:= XWhitePixel (prDisplay, nScreenNum);
…
prGC:= XCreateGC(prDisplay, XRootWindow (prDisplay, nScreenNum), (GCForeground
ORGCBackground), @rValues);
Вызов XCreateGC() - не единственный способ создания графического контекста. Так, например, новый контекст может быть получен из уже существующего GC с помощью XCopyGC().
Когда контекст порожден, его атрибуты могут изменяться процедурой XChangeGC(). Например:
rValues.line_width:= 10;
XChangeGC (prDisplay, prGC, GCLineWidth, @rValues);
Приведенный фрагмент кода меняет ширину линий, рисуемых с помощью графического контекста.
Для того, чтобы получить значение полей GC, используется процедура XGetGCValues().
1.2.2 Характеристики графического контекста
В предыдущем разделе мы говорили, что GC имеет ряд атрибутов, воздействующих на вывод изображений. Для текста это цвет и шрифт, для линий - цвет и толщина и т.д. Как уже упоминалось выше, атрибуты контекста задаются в момент его создания. Потом они могут меняться с помощью функции XChangeGC(). Кроме того, X поддерживает специальные функции для изменения параметров GC.
Ниже перечисляются основные характеристики графического контекста и процедуры, меняющие их.
Режим рисования(поле Xfunction в структуре TXGCValues) указывает, каким образом комбинируются при рисовании цвет графики и цвет изображения, на которое накладывается графика. Данное поле задает некоторую логическую функцию. Возможные значения: