InfoCity
InfoCity - виртуальный город компьютерной документации
Реклама на сайте







Размещение сквозной ссылки

 

Краткое введение в MOTIF


feska@inbox.ru


Я решил посвятить небольшую оду библиотеке MOTIF и ее меньшой (и совершенно бесплатной) сестричке LESSTIF. Сведения, помещенные на этой странице будут полезны тем, кто только начинает знакомство с программированием под X-Window. Перед вами, по сути дела, русскоязычное предисловие к programmer guid'ам, размещенным здесь. Я приведу лишь начальные сведения, полезные для дальнейшей работы с англоязычной документацией.

Что такое MOTIF/LESSTIF


     MOTIF - коммерческая сишная библиотека, предназначенная для создания графического пользовательского интерфейса. Однажды почитатели MOTIF, не желавшие платить за нее, собрались и написали совместимую с MOTIF библиотеку - LESSTIF.

Как работает X Window и что такое Xt


     Элементы интерфейса X Window (окна, поля ввода, списки и т.п.) называются WIDGET'ами.      X Window работает по технологии клиент-сервер. X сервер выполняет запросы WIDGET'ов, управляет очередями событий, направляет ввод на WIDGET'ы, имеющие фокус и т.д.      Для облегчения жизни программистов была создана библиотека Xt. С ее помощью можно создавать WIDGET'ы, задавать и изменять их параметры (цвет, геометрия, шрифты), управлять их поведением и т.п. Функции в Xtlib начинаются обычно с Xt: XtSetValues - установить некие значения; XtManageChild - показать WIDGET... В Xt описаны лишь базовые WIDGET'ы - окна. Все остальное создается при помощи библиотек, основывающихся на Xt: MOTIF, LESSTIF, QT и других.

Ресурсы WIDGET'ов


     Каждый WIDGET обладает набором свойств(ресурсов). Сюда входят размеры, цвет, особенности поведения, предопределенные вызовы callback функций и т.п. Каждый ресурс имеет свое имя. Например: XmNvisibleItemCount - количество элементов, видимых в Scrolled List, XmNselectionPolicy - константа, определяющая возможность выбора элементов. Свойства устанавливаются функциями XtSetArg, XtSetValues, XtVaCreateWidget (см. ниже).

MOTIF - программа


    Программа состоит из двух главных частей:
     1. инициализация WIDGET'ов
     2. обработка событий

инициализация WIDGET'ов


включает в себя создание, изменение свойств, показ.
    WIDGET'ы можно создать двумя путями:
1.используя Xt функцию XtCreateWidget
2.используя MOTIF функции XmCreateИмяWIDGET для соответствующих WIDGET'ов
    Задавать свойства WIDGET'ов можно и до и после их создания. В первом случае используется функция XtSetArg:

/******************************************************/
Widget text;
Arg args[10];
int n;
.
.
.
n = 0;
XtSetArg(args[n], XmNrows, 10); n++; /* задаем количество строк; увеличиваем счетчик аргументов */
XtSetArg(args[n], XmNcolumns, 80); n++; /* задаем количество столбцов; увеличиваем счетчик аргументов */
text = XmCreateText("text", parent, args, n); /* создаем WIDGET. parent - родительский WIDGET (например, головное окно) */
/******************************************************/

В этом примере создается WIDGET text размером 10 строк на 80 колонок. После создания WIDGET его свойства можно изменять при помощи функции XtSetValues.

/******************************************************/
Widget text;
Arg args[10];
int n;
.
.
.
n = 0;
XtSetArg(args[n], XmNrows, 10); n++; /* задаем количество строк; увеличиваем счетчик аргументов */
text = XmCreateText("text", parent, args, n); /* создаем WIDGET.*/
XtSetValues(text, XmNcolumns, 80,NULL); /* задаем количество столбцов */
/******************************************************/
Следующий пример показывает как инициализировать приложение, создать WIDGET'ы и показать их:
#include <Xm/Frame.h>
#include <Xm/RowColumn.h>
#include <Xm/PanedW.h>
#include <Xm/TextF.h>

#define BCOLOR 0x9
#define FCOLOR 0x0


Widget toplevel,sw,text,fram,bback,bnext,btop;
Pixmap pback,pnext,ptop;
XFontStruct *font=NULL;
XmFontList fontlist=NULL;
char *namelist="-cronyx-courier-bold-r-normal-*-*-100-*-*-m-*-koi8r-1";


//////////////////////////////////////////////////////////////////


main(argc, argv)
char *argv[];

{
XtAppContext app;
Arg args[6],al[10];

int ac;

toplevel = XtVaAppInitialize(&app, "test", NULL, 0, &argc, argv, NULL, NULL); //инициализация приложения
font=XLoadQueryFont(XtDisplay(toplevel),namestring);
fontlist=XmFontListCreate(font,XmSTRING_DEFAULT_CHARSET);
XtVaSetValues(toplevel,XmNfontList,fontlist,NULL);
XtVaSetValues(toplevel,XmNbuttonFontList,fontlist,NULL);
XtVaSetValues(toplevel,XmNallowShellResize,True,NULL);


ac=0;
XtSetArg(al[ac],XmNresizeHeight,True); ac++;
XtSetArg(al[ac],XmNresizeWidth,True); ac++;
sw=XmCreateRowColumn(toplevel,"scrw",al,ac);

ac=0;
XtSetArg(al[ac],XmNrubberPositioning ,True ); ac++;
fram=XmCreateForm (sw, "fram", al, ac);
pback=XmGetPixmap(XtScreen(toplevel), "back", 8, 0);
pnext=XmGetPixmap(XtScreen(toplevel), "next", 8, 0);
ptop=XmGetPixmap(XtScreen(toplevel), "top", 8, 0);

ac=0;
XtSetArg(al[ac], XmNbackground, BCOLOR);ac++;
XtSetArg(al[ac],XmNleftAttachment ,XmATTACH_FORM); ac++;
XtSetArg(al[ac],XmNrecomputeSize ,True); ac++;
XtSetArg(al[ac], XmNlabelType, XmPIXMAP); ac++;
XtSetArg(al[ac],XmNarmPixmap ,pback); ac++;
bback=XmCreatePushButton (fram, "bback", al, ac);

ac=0;
XtSetArg(al[ac],XmNleftWidget ,bback); ac++;
XtSetArg(al[ac],XmNleftAttachment ,XmATTACH_WIDGET); ac++;
XtSetArg(al[ac],XmNrecomputeSize ,True); ac++;
XtSetArg(al[ac], XmNlabelType, XmPIXMAP); ac++;
XtSetArg(al[ac],XmNarmPixmap ,pnext); ac++;
bnext=XmCreatePushButton (fram, "bback", al, ac);

ac=0;
XtSetArg(al[ac],XmNleftWidget ,bnext); ac++;
XtSetArg(al[ac],XmNleftAttachment ,XmATTACH_WIDGET); ac++;
XtSetArg(al[ac],XmNrecomputeSize ,True); ac++;
XtSetArg(al[ac], XmNlabelType, XmPIXMAP); ac++;
XtSetArg(al[ac],XmNarmPixmap ,ptop); ac++;
btop=XmCreatePushButton (fram, "bback", al, ac);

XtSetArg(al[ac],XmNeditMode,XmMULTI_LINE_EDIT); ac++;
XtSetArg(al[ac],XmNeditable,False); ac++;
XtSetArg(al[ac], XmNheight, 600); ac++;
XtSetArg(al[ac], XmNwidth, 800); ac++;
XtSetArg(al[ac],XmNfontList,fontlist); ac++;
XtSetArg(al[ac],XmNwordWrap ,True); ac++;
text=XmCreateText(sw,"lbl",al,ac);

XtSetArg(args[0], XmNbackground, BCOLOR);
XtSetArg(args[1], XmNborderColor, BCOLOR);
XtSetArg(args[2], XmNforeground, FCOLOR);

XtSetValues(cont,args,3);

XtManageChild(sw); //показать WIDGET'ы
XtManageChild(fram);
XtManageChild(bback);
XtManageChild(bnext);
XtManageChild(btop);
XtManageChild(cont);

XtRealizeWidget(toplevel); // показать главное окно

XtAppMainLoop(app); //запустить цикл обработки событий
return 0;
}

обработка событий


     Обработка событий может вестись несколькими способами:
     1.Использование callback функций
     2.Использование функций-трансляторов
     3.Создание собственных обработчиков.
Callback функции вызываются при выполнении определенных действий с WIDGET'ом. Например, двойной щелчок в WIDGET'е List приводит к выполнению XmNdefaultActionCallback. Чтобы заставить WIDGET вызывать свою callback функцию нужно указать ее имя в вызове функции XtAddCallback. Например вызов XtAddCallback(list_w,XmNdefaultActionCallback , choose_item,list_w) приведет к тому, что двойной щелчок в WIDGET'е list_w будет обрабатываться пользовательской функцией "choose_item()".

Под трансляцией понимается сопоставление событию, произошедшему в WIDGET'е одной или нескольких функций. Составляется таблица трансляции в следующем формате:
<Btn1Down>,<Btn1Up> : click_action()
<Key>space : action_2()
Слева от двоеточия вводится описание события. Это может быть единичное событие (в нашем случае <Key>space - нажатие клавиши "пробел") или последовательность событий (<Btn1Down>,<Btn1Up> - нажата и отпущена правая кнопка мыши). Справа от двоеточия приводится список вызовов одной или нескольких функций. Это могут быть как функции пользователя так и предопределенные функции WIDGET'а. Пример использования транслятора:
static XtActionsRec acts[] = {
{"Action1", Action1},
{"Prv", Prv},
{"Nxt", Nxt}
};

Widget list,rowcol;
static XtTranslations parsed_xlations;
static char addXlations[] = "\
#replace<Key>osfDown: ListNextItem() Nxt() Action1() \n\
<Key>osfUp: ListPrevItem() Prv() Action1()";


XtAppAddActions(app, acts, XtNumber(acts));

parsed_xlations = XtParseTranslationTable(addXlations);
.
.
.
list=XmCreateText(rowcol,"lst",al,ac);
XtOverrideTranslations(list,parsed_xlations);
.
.
.
Nxt(){
.
.
.
}
Prv(){
.
.
.
}
Action1(){
.
.
.
}
В данном случае мы обрабатываем нажатия клавиш "стрелка вверх" (<Key>osfUp) и "стрелка вниз" (<Key>osfDown) в WIDGET'е ScrolledList. Nxt(), Prv(), Action1() - Функции пользователя; ListNextItem(), ListNextItem() - предопределенные функции WIDGET'а. Опция "#replace" в строке addXlations[] означает, что новая таблица трансляции заменит предопределенную. Возможны и другие опции.

Обработчики событий можно добавить при помощи функции XtAddEventHandler. Например:
XtAddEventHandler(text1, PointerMotionMask, FALSE,EH1, NULL);
XtAddEventHandler(text1, ButtonPressMask , FALSE,EH2, NULL);
XtAddEventHandler(text1, ButtonReleaseMask, FALSE,EH3, NULL);
Здесь text1 - WIDGET; PointerMotionMask, ButtonPressMask, ButtonReleaseMask - события; EH1, EH2, EH3 - пользовательские функции - обработчики событий.
Возможно, не самый лучший, но все же работающий пример приложения с использованием библиотеки Lesstif можно взять здесь.
    Залежалая новость: библиотеку Motif теперь можно получить совершенно бесплатно. Подробности на http://www.motifzone.net. "Весит" RPM для разработчика около 27 Мб. Его можно взять например здесь. Кроме того там же нужно взять пакет со вспомогательными файлами размером 2,6 Мб.
   Пакет содержит множество примеров, которые после инсталляции попадают в каталог /usr/X11R6/xmdemos. Полный набор programmer guid'ов в формате ps находится в /usr/doc/openmotif-devel... Читать их с помощью gv - сущее наказание. Тем , кому PostScript не по душе предлагается скачать документацию в формате PDF с http://www.motifzone.net. Кроме того в /usr/X11R6/bin можно найти кучу демонстрационных программ.
    Первые впечаиления: то, что работало под Lesstif, под Motif не работает. В частности, программа слетает на вызове XmCreateText и любых других операциях с Text WIDGET'ом. Впрочем, в фирменных демонстрашках все работает, так что, возможно, это мои глюки.


Реклама на InfoCity

Яндекс цитирования



Финансы: форекс для тебя








1999-2009 © InfoCity.kiev.ua