X Window - elka.pw
Transkrypt
X Window - elka.pw
X Window Waldemar Grabski Programowanie Aplikacji Interakcyjnych Cechy systemu X Window • • • • • System graficzny zorientowany sieciowo Architektura klient - serwer Przezroczysty sieciowo Niezależny od systemu operacyjnego Odseparowane obliczenia i wyświetlanie Waldemar Grabski Programowanie Aplikacji Interakcyjnych Nazwy wyświetlaczy i ekranów • W systemie X Window możemy mieć jeden lub kilka ekranów (screen) zawierających okna • Zbiór ekranów nazywany jest wyświetlaczem (display) • W systemie jest uruchamiany oddzielny proces do obsługi każdego wyświetlacza Waldemar Grabski Programowanie Aplikacji Interakcyjnych Zmienna DISPLAY • Zmienna DISPLAY określa, gdzie będzie wyświetlane wyjście aplikacji (klienta) export DISPLAY = helmut.ii.pw.edu.pl:0.0 • Akreślenie maszyn, które będą mogły korzystać z usług serwera X Window xhost +nt01.nt140.ii.pw.edu.pl xhost +nt01.nt140.ii.pw.edu.pl Waldemar Grabski Programowanie Aplikacji Interakcyjnych Hierarchia okien • Okna ułożone są w hierarchię (ojciec-dzieci) • Korzeniem drzewa jest okno „root window” zajmujące całą powierzchnię ekranu • Każde okno poza „root window” posiada rodzica • Okno dziecka może wystawać poza obszar swojego rodzica, ale wyświetlanie jest obcinane do obszaru rodzica Waldemar Grabski Programowanie Aplikacji Interakcyjnych Hierarchia okien Waldemar Grabski Programowanie Aplikacji Interakcyjnych Geometria okna • Współrzędne podawane są w punktach – położenie okna określane jest względem współrzędnych rodzica (położenie lewego górnego rogu ramki okna) – podajemy szerokość i wysokość okna – podajemy szerokość ramki okna – współrzędne wewnątrz okna względem lewego górnego rogu wewnętrznego ramki Waldemar Grabski Programowanie Aplikacji Interakcyjnych Zarządca okien • Zarządca okien jest to specjalna aplikacja (klient) zapewniająca: – zmianę położenia i rozmiaru okien – przełączanie pomiędzy oknami – określanie, które okno posiada input focus • Interakcje pomiędzy oknami określa standard ICCCM (Inter-Client Communications Conventions Manual) Waldemar Grabski Programowanie Aplikacji Interakcyjnych Zarządca okien • Dodaje okno pomiędzy „root window” a głównym oknem aplikacji oraz elementy dekoracyjne (pasek tytułu, przyciski, menu ...) root Okno dodane przez zarządcę Okno aplikacji Waldemar Grabski Pasek tytułu ... Programowanie Aplikacji Interakcyjnych Zarządca okien • Terminal uruchomiony bez zarządcy okien • Terminal uruchomiony z zarządcą okien Waldemar Grabski Programowanie Aplikacji Interakcyjnych Architektura aplikacji • X Protocol – protokół komunikacji klienta z serwerem • Xlib – biblioteka zawierająca funkcje umożliwiające korzystanie z X Protocol • Xt Intrinsics – biblioteka umożliwiająca korzystanie z widgetów (obiektów reprezentujących elementy aplikacji np. menu, przyciski) • X Toolkit – zestaw widget-ów • X Aplikaction - aplikacja Waldemar Grabski Programowanie Aplikacji Interakcyjnych Żądania i zdarzenia • Żądania (requests) są wysyłane przez klienta do serwera w celu wykonania operacji np. narysowania linii • Zdarzenia (events) są wysyłane przez serwer do klienta: – input events – zdarzenia związane z myszą i klawiaturą – expose events – zdarzenia wysyłane do klienta jeśli coś stanie się z oknem Waldemar Grabski Programowanie Aplikacji Interakcyjnych Buforowanie żądań • Każde żądanie wysyłane przez klienta jest buforowane Waldemar Grabski Programowanie Aplikacji Interakcyjnych Buforowanie żądań • Żądania są wysyłane do X serwera gdy: – bufor zostanie zapełniony – zostanie wywołana funkcja opróżniająca bufor – zostanie wywołana funkcję pobierającą zdarzenie, która czeka na to zdarzenie – zostanie wywołana funkcja, która wymaga potwierdzenia z serwera Waldemar Grabski Programowanie Aplikacji Interakcyjnych Xlib - konwencja biblioteki Nazwy funkcji i struktur danych – zaczynają się od X – wszystkie słowa w nazwach zaczynają się od dużej litery (pozostałe litery małe) • Nazwy makropoleceń – nie zaczynają się od X – wszystkie słowa w nazwach zaczynają się od dużej litery (pozostałe litery małe) • Nazwy pól struktur – Słowa w całości pisane małymi literami – słowa oddzielone znakiem ‘_’ Waldemar Grabski Programowanie Aplikacji Interakcyjnych Xlib - konwencja biblioteki Kolejność argumentów • display jeśli występuje jest na pierwszej pozycji • zasobów (okno, czcionka ...) jeśli występują są bezpośrednio za argumentem display • kontekst graficzny występuje za zasobami (np. drawable) • argument źródłowy zawsze poprzedza argument docelowy • Parametry określające położenie i rozmiar występują w kolejności: x, y, width, hight • jeśli maska występuje w połączeniu ze strukturą maska zawsze poprzedza strukturę Waldemar Grabski Programowanie Aplikacji Interakcyjnych Połączenie z X Serwerem • Nawiązywanie połączenia z X serwerem Display * XOpenDisplay( char * display_name ) – display_name – nazwa ekranu • helmut.ii.pw.edu.pl:0.0 • NULL - połączenie z X serwerem określony przez zmienną środowiskową DISPLAY – rezultatem jest wskazanie na strukturę Display opisującą połączenie z X serwerem • Zamykanie połączenia z X serwerem XCloseDisplay( Display * display ) – display – wskazanie na strukturę opisującą połączenie z Xserwerem Waldemar Grabski Programowanie Aplikacji Interakcyjnych X Serwer przechowuje zasoby • Okna • Kontekst graficzny – struktura przechowująca (na serwerze) atrybuty graficzne takie jak kolor, czcionka itp. (wprowadzony w X11) • Czcionki • Kursory • Colormaps – umożliwia określenie koloru RGB na podstawie wartości punktu (aplikacja nie powinna instalować własnej mapy kolorów lecz informować menadżera okien jakiej mapy potrzebuje) • Pixmaps – blok pamięci w którym możemy rysować tak jak na ekranie Waldemar Grabski Programowanie Aplikacji Interakcyjnych Xlib – kategorie zdarzeń Kategoria Keyboard events Pointer events Zdarzenia KeyPress, KeyRelease ButtonPress, ButtonRelease, MotionNotify Window crossing events Input focus events Keymap state notification event EnterNotify, LeaveNotify FocusIn, FocusOut KeymapNotify Exposure events Structure control events Expose, GraphicsExpose, NoExpose CirculateRequest, ConfigureRequest, MapRequest, ResizeRequest CirculateNotify, ConfigureNotify, CreateNotify, DestroyNotify, GravityNotify, MapNotify, MappingNotify, ReparentNotify, UnmapNotify, VisibilityNotify Window state notification events Colormap state notification event ColormapNotify Client communication events ClientMessage, PropertyNotify, SelectionClear, SelectionNotify, SelectionRequest Waldemar Grabski Programowanie Aplikacji Interakcyjnych Xlib – zdarzenia Mask ButtonMotionMask ButtonPressMask ButtonReleaseMask EnterWindowMask LeaveWindowMask ExposureMask KeyPressMask KeyReleaseMask PointerMotionMask Event MotionNotify ButtonPress ButtonRelease EnterNotify LeaveNotify Expose KeyPress KeyRelease MotionNotify Waldemar Grabski Event Type XPointerMovedEvent XButtonPressedEvent XButtonReleasedEvent XEnterWindowEvent XLeaveWindowEvent XExposeEvent XKeyPressedEvent XKeyReleasedEvent XPointerMovedEvent Structure XMotionEvent XButtonEvent XButtonEvent XCrossingEvent XCrossingEvent XKeyEvent XMotionEvent Programowanie Aplikacji Interakcyjnych Xlib - zdarzenia • Aby otrzymywać od serwera zdarzenia musimy ich zażądać ich przesyłania XSelectInput( Display * display, Window w, long event_mask ) – display – określa połączenie z X serwerem – w – określa okno – event_mask – maska określająca jakie zdarzenia nas interesują • Zdarzenia pobieramy z kolejki związanej z połączeniem z X serwerem XNextEvent( Display *display; XEvent * event_return ) XWindowEvent( Display * display; Window w, long event_mask, XEvent * event_return ) Waldemar Grabski Programowanie Aplikacji Interakcyjnych Struktura XExposeEvent • Struktura XExposeEvent zawiera parametry specyficzne dla zdarzenia typedef struct { int type; unsigned long serial; Bool send_event; Display *display; Window window; int x, y; int width, height; int count; } XExposeEvent; Waldemar Grabski /* Expose */ /* # of last request processed by server */ /* true if this came from a SendEvent request */ /* Display the event was read from */ /* if nonzero, at least this many more */ Programowanie Aplikacji Interakcyjnych Struktura XButtonExent • Struktura XButtonEvent zawiera parametry specyficzne dla zdarzenia typedef struct { int type; /* ButtonPress or ButtonRelease */ unsigned long serial; /* # of last request processed by server */ Bool send_event; /* true if this came from a SendEvent request */ Display *display; /* Display the event was read from */ Window window; /* „event” window it is reported relative to */ Window root; /* root window that the event occurred on */ Window subwindow; /* child window */ Time time; /* milliseconds */ int x, y; /* pointer x, y coordinates in event window */ int x_root, y_root; /* coordinates relative to root */ unsigned int state; /* key or button mask */ unsigned int button; /* detail */ Bool same_screen; /* same screen flag */ } XButtonEvent; Waldemar Grabski Programowanie Aplikacji Interakcyjnych Xlib - unia XEvent • Unia XEvent typedef union _XEvent { int type; /* must not be changed */ XAnyEvent xany; XKeyEvent xkey; XButtonEvent xbutton; XMotionEvent xmotion; XCrossingEvent xcrossing; ... XMappingEvent xmapping; XErrorEvent xerror; XKeymapEvent xkeymap; long pad[24]; } XEvent; Waldemar Grabski Programowanie Aplikacji Interakcyjnych Xlib - unia XEvent • Struktura XAnyEvent zawiera pola wspólne dla wszystkich struktur opisujących zdarzenia typedef struct { int type; unsigned long serial; /* # of last request processed by server */ Bool send_event; /* true if this came from a SendEvent request */ Display *display; /* Display the event was read from */ Window window; } XAnyEvent; Waldemar Grabski Programowanie Aplikacji Interakcyjnych Xlib - okna • Tworzenie i usuwanie okna Window XCreateSimpleWindow( Display * display, Window parent, int x, int y, unsigned int width, unsigned int height, unsigned int border_width, unsigned long border, unsigned long background ) • Usuwanie okna XDestroyWindow( Display * display, Window w ) • Mapowanie okna XMapWindow( Display * display, Window w ) XUnmapWindow( Display * display, Window w ) Waldemar Grabski Programowanie Aplikacji Interakcyjnych Xlib – kontekst graficzny • Kontekst graficzny jest strukturą przechowującą (na serwerze) atrybuty graficzne takie jak kolor, czcionka itp. (wprowadzony w X11) • Tworzenie kontekstu graficznego GC XCreateGC( Display *display, Drawable d, unsigned long valuemask, XGCValues * values ) • Usuwanie kontekstu graficznego XFreeGC( Display *display, GC gc ) • Zmiana parametrów kontekstu XChangeGC( Display * display, GC gc, unsigned long valuemask, XGCValues * values ) Waldemar Grabski Programowanie Aplikacji Interakcyjnych Xlib – kontekst graficzny typedef struct { int function; /* logical operation */ unsigned long plane_mask; /* plane mask */ unsigned long foreground; /* foreground pixel */ unsigned long background; /* background pixel */ int line_width; /* line width (in pixels) */ int line_style; /* LineSolid, LineOnOffDash */ int cap_style; /* CapNotLast, CapButt */ int join_style; /* JoinMiter, JoinRound, JoinBevel */ int fill_style; /* FillSolid, FillTiled, FillStippled */ int fill_rule; /* EvenOddRule, WindingRule */ int arc_mode; /* ArcChord, ArcPieSlice */ ... } XGCValues; #define GCFunction (1L<<0) #define GCPlaneMask (1L<<1) #define GCForeground (1L<<2) #define GCBackground (1L<<3) #define GCLineWidth (1L<<4) #define GCLineStyle (1L<<5) Waldemar Grabski Programowanie Aplikacji Interakcyjnych Aplikacja draw #include <X11/Xlib.h> #include <unistd.h> class Line { public: int x1; int y1; int x2; int y2; Line * next; Line() { x1 = y1 = x2 = y2 = 0; next = NULL; } void draw( Display * display, Window window, GC gc ) { XDrawLine( display, window, gc, x1, y1, x2, y2 ); } }; Waldemar Grabski Programowanie Aplikacji Interakcyjnych Aplikacja draw main() { Line * lines = NULL; // Open the display Display *dpy = XOpenDisplay( NULL ); // Get some colors int blackColor = BlackPixel(dpy, DefaultScreen(dpy)); int whiteColor = WhitePixel(dpy, DefaultScreen(dpy)); // Create the window Window w = XCreateSimpleWindow( dpy, DefaultRootWindow(dpy), 0, 0, 200, 100, 0, blackColor, blackColor ); // "Map" the window (that is, make it appear on the screen) XMapWindow(dpy, w); // Create a "Graphics Context" GC gc = XCreateGC(dpy, w, 0, NULL ); GC gcXor = XCreateGC(dpy, w, 0, NULL ); XSetFunction( dpy, gcXor, GXxor ); // Tell the GC we draw using the white color XSetForeground(dpy, gc, whiteColor); XSetForeground(dpy, gcXor, whiteColor); Waldemar Grabski Programowanie Aplikacji Interakcyjnych Aplikacja draw XSelectInput(dpy, w, ExposureMask | PointerMotionMask | ButtonPressMask | ButtonReleaseMask ); bool done = false; bool drawing = false; int x = 0; int y = 0; int xTmp = 0; int yTmp = 0; while( ! done ) { XEvent e; XNextEvent( dpy, & e ); switch( e.type ) { case ButtonPress : { ... } break; case ButtonRelease : { ... } break; case MotionNotify : { ... } break; case Expose : { ... } break; } } XFreeGC( dpy, gc ); XFreeGC( dpy, gcXor ); XDestroyWindow( dpy, w ); XCloseDisplay( dpy ); } Waldemar Grabski Programowanie Aplikacji Interakcyjnych Aplikacja draw case ButtonPress : switch( e.xbutton.button ) { case Button1 : x = xTmp = e.xbutton.x; y = yTmp = e.xbutton.y; XDrawLine( dpy, w, gcXor, x, y, xTmp, yTmp ); XFlush( dpy ); break; case Button2 : case Button3 : done = true; break; }//switch break; Waldemar Grabski drawing = true; Programowanie Aplikacji Interakcyjnych Aplikacja draw case ButtonRelease : switch( e.xbutton.button ) { case Button1 : if( drawing ) { drawing = false; XDrawLine( dpy, w, gcXor, x, y, xTmp, yTmp ); Line * l = new Line; l->x1 = x; l->y1 = y; l->x2 = e.xbutton.x; l->y2 = e.xbutton.y; l->next = lines; lines = l; l->draw( dpy, w, gc ); XFlush( dpy ); } break; }//switch break; Waldemar Grabski Programowanie Aplikacji Interakcyjnych Aplikacja draw case MotionNotify : if( drawing && (e.xmotion.state & Button1Mask) ) { XDrawLine( dpy, w, gcXor, x, y, xTmp, yTmp ); xTmp = e.xmotion.x; yTmp = e.xmotion.y; XDrawLine( dpy, w, gcXor, x, y, xTmp, yTmp ); XFlush( dpy ); } break; case Expose : if( e.xexpose.count == 0 ) { Line * l = lines; while( l != NULL ) { l->draw( dpy, w, gc ); l = l->next; } XFlush( dpy ); } break; Waldemar Grabski Programowanie Aplikacji Interakcyjnych X Toolkit Intrinsics • Biblioteka Xt Intrinsics jest kolejną warstwą po Xlib • Wprowadza pojęcie obiektu ekranowego widget • Ułatwia obsługę zdarzeń • Umożliwia tworzenie zestawów obiektów ekranowych (toolkit) takich jak: – OSF/Motif – Athena – OPEN LOOK Waldemar Grabski Programowanie Aplikacji Interakcyjnych X Toolkit Intrinsics Waldemar Grabski Programowanie Aplikacji Interakcyjnych Obiekt ekranowy - widget • Jest obiektem w sensie programowania obiektowego (implementacja w języku C) • Można rozszerzać jego funkcjonalność (dziedziczenie) • Jest (zwykle) związany z oknem • Posiada: – atrybuty np. położenie, rozmiar, identyfikator okna – wskazania na funkcje obsługi zdarzeń – wskazania na funkcje „callback” Waldemar Grabski Programowanie Aplikacji Interakcyjnych Widget - atrybuty typedef struct { String name; XtArgVal value; } Arg; /* Name of resource * /* Its value */ Widget XtCreateManagedWidget( String name, WidgetClass widget_class, Widget parent, ArgList args, Cardinal num_args ); void XtSetArg( Arg arg, String name, XtArgVal value ); void XtSetValues( Widget object, ArgList args, Cardinal num_args ); Waldemar Grabski Programowanie Aplikacji Interakcyjnych Widget – funkcje obsługi zdarzeń typedef void (*XtEventHandler)( Widget w, XtPointer client_data, XEvent * event, Boolean * continue_to_dispatch ); void XtAddEventHandler( Widget w, EventMask event_mask, Boolean nonmaskable, XtEventHandler proc, XtPointer client_data ); void XtRemoveEventHandler( Widget w, EventMask event_mask, Boolean nonmaskable, XtEventHandler proc, XtPointer client_data); Waldemar Grabski Programowanie Aplikacji Interakcyjnych Widget – funkcje „callback” typedef void (*XtCallbackProc)( Widget w, XtPointer client_data, XtPointer call_data ); void XtAddCallback( Widget w, String callback_name, XtCallbackProc callback, XtPointer client_data ); void XtRemoveCallback( Widget w, String callback_name, XtCallbackProc callback, XtPointer client_data ); Waldemar Grabski Programowanie Aplikacji Interakcyjnych Inicjowanie biblioteki XtIntrinsics • W aplikacji obiekty ekranowe tworzą hierarchię (drzewo), którego korzeniem jest obiekt ekranowy zwrócony przez funkcję inicjującą bibliotekę XtIntrinsics Widget XtInitialize( String shell_name, String application_class, XrmOptionDescRec options, Cardinal num_options, int * argc, String argv ); Waldemar Grabski Programowanie Aplikacji Interakcyjnych Elementy aplikacji - XtIntrinsics • Inicjowanie biblioteki Widget XtInitialize( ... ); • Utworzenie i zainicjowanie obiektów ekranowych Widget XtCreateManagedWidget( ... ); – Ustawienie atrybutów – Rejestrowanie funkcji callback – Rejestrowanie procedur obsługi zdarzeń Waldemar Grabski Programowanie Aplikacji Interakcyjnych Elementy aplikacji - XtIntrinsics • Realizacja obiektów ekranowych void XtRealizeWidget( Widget w ); • Pętla obsługi zdarzeń XEvent theEvent; while( 1 ) { XtNextEvent( & theEvent ); XtDispatchEvent( & theEvent ); } lub XtMainLoop(); Waldemar Grabski Programowanie Aplikacji Interakcyjnych Przykładowa aplikacja char quit_label[] = "Press here to exit ..."; void button_pushed( Widget w, caddr_t client_data, XmAnyCallbackStruct * call_data ) { XtCloseDisplay( XtDisplay( w ) ); exit( 0 ); } void main( int argc, char ** argv ) { Arg args[ 1 ]; Widget main_widget, quit_button; main_widget = XtInitialize( argv[ 0 ], "XMdemo", NULL, 0, & argc, argv ); XtSetArg( args[ 0 ], XmNlabelString, XmStringCreateLtoR( quit_label, XmSTRING_DEFAULT_CHARSET ) ); quit_button = XtCreateManagedWidget( "Exit", xmPushButtonWidgetClass, main_widget, (ArgList)args, 1 ); XtAddCallback( quit_button, XmNactivateCallback, button_pushed, NULL ); XtRealizeWidget( main_widget ); XtMainLoop(); } Waldemar Grabski Programowanie Aplikacji Interakcyjnych Przykładowa aplikacja - Hello void quit_action( Widget w, caddr_t client_data, XmAnyCallbackStruct * call_data ) { XtCloseDisplay( XtDisplay( w ) ); exit( 0 ); } void main( int argc, char ** argv ) { Arg args[ 10 ]; Widget main_widget, form_widget, hello_message, exit_button; main_widget = XtInitialize( argv[ 0 ], "XHello", NULL, 0, & argc, argv ); form_widget = XtCreateManagedWidget( "Form", xmFormWidgetClass, main_widget, NULL, 0 ); XtSetArg( args[ 0 ], XmNtopAttachment, XmATTACH_FORM ); XtSetArg( args[ 1 ], XmNleftAttachment, XmATTACH_FORM ); XtSetArg( args[ 2 ], XmNlabelString, XmStringCreateLtoR( "Exit", XmSTRING_DEFAULT_CHARSET ) ); exit_button = XtCreateManagedWidget( "Exit", xmPushButtonWidgetClass, form_widget, (ArgList)args, 3 ); XtAddCallback( exit_button, XmNactivateCallback, quit_action, NULL ); Waldemar Grabski Programowanie Aplikacji Interakcyjnych Przykładowa aplikacja - Hello XtSetArg( args[ 0 ], XmNtopAttachment, XmATTACH_WIDGET ); XtSetArg( args[ 1 ], XmNtopWidget, exit_button ); XtSetArg( args[ 2 ], XmNbottomAttachment, XmATTACH_FORM ); XtSetArg( args[ 3 ], XmNleftAttachment, XmATTACH_FORM ); XtSetArg( args[ 4 ], XmNrightAttachment, XmATTACH_FORM ); XtSetArg( args[ 5 ], XmNlabelString, XmStringCreateLtoR( "Hello", XmSTRING_DEFAULT_CHARSET ) ); hello_message = XtCreateManagedWidget( "Hello", xmLabelWidgetClass, form_widget, (ArgList)args, 6 ); XtRealizeWidget( main_widget ); XtMainLoop(); } Waldemar Grabski Programowanie Aplikacji Interakcyjnych Obiekty ekranowe - dziedziczenie • Każdy obiekt ekranowy jest definiowany przez dwie struktury – reprezentującą klasę – reprezentującą instancję Waldemar Grabski Programowanie Aplikacji Interakcyjnych Obiekty ekranowe - dziedziczenie • Wyprowadzenie nowego obiektu ekranowego B (pochodnego od A) polega na: – zdefiniowaniu nowej struktury reprezentującej klasę – zdefiniowaniu nowej struktury reprezentującej instancję Waldemar Grabski Programowanie Aplikacji Interakcyjnych Obiekty ekranowe - dziedziczenie Waldemar Grabski Programowanie Aplikacji Interakcyjnych Obiekty ekranowe - XtIntrinsics • Core – klasa bazowa dla wszystkich obiektów ekranowych, – w rzeczywistości wyprowadzone od klas: Object, RectObj, WindowObj, – zawiera zestaw zasobów dziedziczonych przez klasy pochodne • Composite – wyprowadzona bezpośrednio od Core – używana jako kontener dla innych obiektów • Shell – zapewnia współpracę z menadżerem okien, zarządza tylko jednym dzieckiem Waldemar Grabski Programowanie Aplikacji Interakcyjnych Obiekty ekranowe - XtIntrinsics Waldemar Grabski Programowanie Aplikacji Interakcyjnych Obiekty ekranowe - Motif • XmPrimitive obiekt ekranowy reprezentujący przyciski, etykiety, suwaki itd... • XmGadget nie reprezentuje okna, musi mieć rodzica (widget) i w nim może wyświetlać swoje wyjście • XmManager jest kontenerem dla innych widgetów Waldemar Grabski Programowanie Aplikacji Interakcyjnych Obiekty ekranowe - Motif Waldemar Grabski Programowanie Aplikacji Interakcyjnych XmPrimitive Waldemar Grabski Programowanie Aplikacji Interakcyjnych XmPrimitive Waldemar Grabski Programowanie Aplikacji Interakcyjnych XmGadget Waldemar Grabski Programowanie Aplikacji Interakcyjnych XmManager Waldemar Grabski Programowanie Aplikacji Interakcyjnych Manager) Waldemar Grabski Programowanie Aplikacji Interakcyjnych XmBulletinBoard Waldemar Grabski Programowanie Aplikacji Interakcyjnych XmBulletinBoard Waldemar Grabski Programowanie Aplikacji Interakcyjnych MenuBar #include <Xm/Xm.h> #include <Xm/MainW.h> #include <Xm/CascadeB.h> void quit_call(...), help_call(...); main(int argc, char **argv) { Widget top_wid, main_w, menu_bar, quit, help; XtAppContext app; Arg arg[1]; /* create application, main and menubar widgets */ top_wid = XtVaAppInitialize(&app, "menu_cascade", NULL, 0, &argc, argv, NULL, NULL); main_w = XtVaCreateManagedWidget("main_window", xmMainWindowWidgetClass, top_wid, NULL); menu_bar = XmCreateMenuBar(main_w, "main_list", NULL, 0); XtManageChild(menu_bar); MenuBar /* create quit widget + callback */ quit = XtVaCreateManagedWidget( "Quit", xmCascadeButtonWidgetClass, menu_bar, XmNmnemonic, 'Q', NULL); XtAddCallback(quit, XmNactivateCallback, quit_call, NULL); /* create help widget + callback */ help = XtVaCreateManagedWidget( "Help", xmCascadeButtonWidgetClass, menu_bar, XmNmnemonic, 'H', NULL); XtAddCallback(help, XmNactivateCallback, help_call, NULL); /* Tell the menubar which button is the help menu XtSetArg(arg[0],XmNmenuHelpWidget,help); XtSetValues(menu_bar,arg,1); XtRealizeWidget(top_wid); XtAppMainLoop(app); } void quit_call(...){ printf("Quitting program\n"); exit(0); } void help_call(...){ printf("Sorry, I'm Not Much Help\n"); } */ Menu main_w = XmCreateMainWindow( toplevel, "main_window", ... ); file = XmStringCreateLocalized("File"); menubar = XmVaCreateSimpleMenuBar( main_w, "menubar", XmVaCASCADEBUTTON, file, 'F', NULL); open = XmStringCreateLocalized("Open..."); quit = XmStringCreateLocalized("Quit"); XmVaCreateSimplePulldownMenu(menubar, "file_menu", 0, file_cb, XmVaPUSHBUTTON, open, 'N', NULL, NULL, XmVaSEPARATOR, XmVaPUSHBUTTON, quit, 'Q', NULL, NULL, NULL); Rozmieszczanie widget-ów #include <Xm/PushB.h> #include <Xm/RowColumn.h> main(int argc, char **argv) { Widget top_widget, rowcol; XtAppContext app; top_widget = XtVaAppInitialize(&app,"rowcol", NULL, 0, &argc, argv, NULL,NULL); rowcol = XtVaCreateManagedWidget("rowcolumn", xmRowColumnWidgetClass, top_widget, NULL); XtVaCreateManagedWidget("button 1", xmPushButtonWidgetClass, rowcol, NULL); XtVaCreateManagedWidget("button 2", xmPushButtonWidgetClass, rowcol, NULL); XtVaCreateManagedWidget("button 3", xmPushButtonWidgetClass, rowcol, NULL); XtVaCreateManagedWidget("button 4", xmPushButtonWidgetClass, rowcol, NULL); XtRealizeWidget(top_widget); XtAppMainLoop(app); } Rozmieszczanie widget-ów #include <Xm/PushB.h> #include <Xm/RowColumn.h> main(int argc, char **argv) { Widget top_widget, rowcol; XtAppContext app; top_widget = XtVaAppInitialize(&app,"rowcol", NULL, 0, &argc, argv, NULL, NULL); rowcol = XtVaCreateManagedWidget("rowcolumn", xmRowColumnWidgetClass, top_widget, XmNorientation, XmHORIZONTAL, NULL); XtVaCreateManagedWidget("button 1", xmPushButtonWidgetClass, rowcol, NULL); XtVaCreateManagedWidget("button 2", xmPushButtonWidgetClass, rowcol, NULL); XtVaCreateManagedWidget("button 3", xmPushButtonWidgetClass, rowcol, NULL); XtVaCreateManagedWidget("button 4", xmPushButtonWidgetClass, rowcol, NULL); XtRealizeWidget(top_widget); XtAppMainLoop(app); } Motif – aplikacja xdialog Waldemar Grabski Programowanie Aplikacji Interakcyjnych Motif – aplikacja xdialog Widget file_dialog = Widget( 0 ), file_sel_box = Widget( 0 ); Widget message_widget; void quit_action( Widget w, caddr_t client_data, XmAnyCallbackStruct * call_data ); void fs_ok( Widget w, caddr_t client_data, XmSelectionBoxCallbackStruct * call_data ); void fs_cancel( Widget w, caddr_t client_data, XmSelectionBoxCallbackStruct * call_data ); void dialog_action( Widget w, caddr_t client_data, XmAnyCallbackStruct * call_data ); void main( int argc, char ** argv ) { Arg args[ 10 ]; Widget main_widget, form_widget, exit_button, load_button; main_widget = XtInitialize( argv[ 0 ], "XDialog", NULL, 0, & argc, argv ); form_widget = XtCreateManagedWidget( "Form", xmFormWidgetClass, main_widget, NULL, 0 ); // utworzenie przycisku Exit XtSetArg( args[ 0 ], XmNtopAttachment, XmATTACH_FORM ); XtSetArg( args[ 1 ], XmNleftAttachment, XmATTACH_FORM ); XtSetArg( args[ 2 ],XmNlabelString,”Exit” ); exit_button = XtCreateManagedWidget( "Exit", xmPushButtonWidgetClass, form_widget, (ArgList)args, 3 ); XtAddCallback( exit_button, XmNactivateCallback, quit_action, NULL ); Waldemar Grabski Programowanie Aplikacji Interakcyjnych Motif – aplikacja xdialog // utworzenie przycisku Load XtSetArg( args[ 0 ], XmNtopAttachment, XmATTACH_FORM ); XtSetArg( args[ 1 ], XmNleftAttachment, XmATTACH_WIDGET ); XtSetArg( args[ 2 ], XmNleftWidget, exit_button ); XtSetArg( args[ 3 ], XmNlabelString, XmStringCreateLtoR( "Dialog", XmSTRING_DEFAULT_CHARSET ) ); load_button = XtCreateManagedWidget( "Load", xmPushButtonWidgetClass, form_widget, (ArgList)args, 4 ); XtAddCallback( load_button, XmNactivateCallback, dialog_action, (caddr_t)main_widget ); // utworzenie etykiety XtSetArg( args[ 0 ], XmNtopAttachment, XmATTACH_WIDGET ); XtSetArg( args[ 1 ], XmNtopWidget, exit_button ); XtSetArg( args[ 2 ], XmNbottomAttachment, XmATTACH_FORM ); XtSetArg( args[ 3 ], XmNleftAttachment, XmATTACH_FORM ); XtSetArg( args[ 4 ], XmNrightAttachment, XmATTACH_FORM ); XtSetArg( args[ 5 ], XmNlabelString, XmStringCreateLtoR( "",XmSTRING_DEFAULT_CHARSET ) ); message_widget = XtCreateManagedWidget( "Hello", xmLabelWidgetClass, form_widget, (ArgList)args, 6 ); XtRealizeWidget( main_widget ); XtMainLoop(); } Waldemar Grabski Programowanie Aplikacji Interakcyjnych Motif – aplikacja xdialog Waldemar Grabski Programowanie Aplikacji Interakcyjnych Motif – aplikacja xdialog void dialog_action( Widget w, caddr_t client_data, XmAnyCallbackStruct * call_data ) { if( file_dialog == Widget( 0 ) ) { Arg args[ 10 ]; Cardinal argcount = 0; XtSetArg( args[ argcount ], XmNdialogStyle, XmDIALOG_MODELESS ); argcount ++; XtSetArg( args[ argcount ], XmNwidth, 300 ); argcount ++; XtSetArg( args[ argcount ], XmNheight, 400 ); argcount ++; file_dialog= XmCreateBulletinBoardDialog((Widget)client_data, "Select File", args, argcount ); XmString dir_mask; argcount = 0; dir_mask = XmStringLtoRCreate( "*", XmSTRING_DEFAULT_CHARSET ); XtSetArg( args[ argcount ], XmNdirMask, dir_mask ); argcount ++; XmString title; title = XmStringLtoRCreate( "Load", XmSTRING_DEFAULT_CHARSET ); XtSetArg( args[ argcount ], XmNfilterLabelString, title ); argcount ++; file_sel_box = XmCreateFileSelectionBox( file_dialog, "File Selection", args, argcount ); XtAddCallback( file_sel_box, XmNokCallback, fs_ok, (caddr_t)file_dialog ); XtAddCallback( file_sel_box, XmNcancelCallback, fs_cancel, (caddr_t)file_dialog ); XmStringFree( dir_mask ); XmStringFree( title ); XtManageChild( file_sel_box ); }//if XtManageChild( file_dialog ); } Waldemar Grabski Programowanie Aplikacji Interakcyjnych Motif – aplikacja xdialog void quit_action( Widget w, caddr_t client_data, XmAnyCallbackStruct * call_data ) { XtCloseDisplay( XtDisplay( w ) ); exit( 0 ); } void fs_ok( Widget w, caddr_t client_data, XmSelectionBoxCallbackStruct * call_data ) { char * file_name; if( XmStringGetLtoR( call_data->value, XmSTRING_DEFAULT_CHARSET, & file_name ) ) { Arg args[ 1 ]; XtSetArg( args[ 0 ], XmNlabelString, XmStringCreateLtoR( file_name, XmSTRING_DEFAULT_CHARSET ) ); XtSetValues( message_widget, args, 1 ); } XtUnmanageChild( (Widget)client_data ); } void fs_cancel( Widget w, caddr_t client_data, XmSelectionBoxCallbackStruct * call_data ) { XtUnmanageChild( (Widget)client_data ); } Waldemar Grabski Programowanie Aplikacji Interakcyjnych