Коротке введення в 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 – програма

Програма складається з двох головних частин:
&nbsp&nbsp&nbsp&nbsp 1. ініціалізація WIDGET’ов
&nbsp&nbsp&nbsp&nbsp 2. обробка подій

ініціалізація WIDGET’ов

включає в себе створення, зміна властивостей, показ.
& NbspWIDGET’и можна створити двома шляхами:
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;
}

обробка подій

Обробка подій може вестися декількома способами:
&nbsp&nbsp&nbsp&nbsp 1.Використання callback функцій
&nbsp&nbsp&nbsp&nbsp 2.Використання функцій-трансляторів
&nbsp&nbsp&nbsp&nbsp 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()
Зліва від двокрапки вводиться опис події. Це може бути одинична подія (в нашому випадку space – натискання клавіші “пробіл”) або послідовність подій (, – Натиснута і відпущена права кнопка миші). Праворуч від двокрапки приводиться список викликів однієї або декількох функцій. Це можуть бути як функції користувача так і зумовлені функції 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(){
.
.
.
}
В даному випадку ми обробляємо натиснення клавіш “стрілка вгору” ( osfUp) і “стрілка вниз” ( 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’ом. Втім, у фірмових демонстрашках все працює, так що, можливо, це мої глюки.

Схожі статті:


Сподобалася стаття? Ви можете залишити відгук або підписатися на RSS , щоб автоматично отримувати інформацію про нові статтях.

Коментарів поки що немає.

Ваш отзыв

Поділ на параграфи відбувається автоматично, адреса електронної пошти ніколи не буде опублікований, допустимий HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

*