a simple motif widget the basic steps involved in creating and displaying this or any other motif...

36
A Simple Motif Widget basic steps involved in creating and displ or any other Motif widget are essentially . is a shell widget with a label widget cont .

Post on 22-Dec-2015

215 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: A Simple Motif Widget The basic steps involved in creating and displaying this or any other Motif widget are essentially the same. This is a shell widget

A Simple Motif Widget

The basic steps involved in creating and displayingthis or any other Motif widget are essentially the same.

This is a shell widget with a label widget containedin it.

Page 2: A Simple Motif Widget The basic steps involved in creating and displaying this or any other Motif widget are essentially the same. This is a shell widget

Basic Steps in a Motif Application

1 Initialize Xt. Open a connection to the X server and create a data structure called an application context.

2 Create a shell, to serve as a container for all other widgets in program (can be combined with step 1)

3 Create widgets, using parameterized calls to Xt routines

4 Register callbacks, which are the functions to be called in response to some user input

Page 3: A Simple Motif Widget The basic steps involved in creating and displaying this or any other Motif widget are essentially the same. This is a shell widget

Basic Steps in a Motif Application (cont'd)

5 Manage all widgets, that is, associate container widgets with their children to keep track of their size and position

6 Realize all widgets, that is, create an X window on the screen and have the widget display itself

7 Handle events. Enter an event loop to receive events from the X server. Events are removed from a queue and dispatched to the appropriate widget for handling (that is, a callback occurs)

Page 4: A Simple Motif Widget The basic steps involved in creating and displaying this or any other Motif widget are essentially the same. This is a shell widget

The "Hello World" C++/Xt/Motif Program

// hello.C, Hello World using C++ and Motif#include <Xm/Xm.h>#include <Xm/Label.h>

void main ( int argc, char **argv ){ Widget label, shell; XtAppContext app; XmString xmstr; Arg args[10]; int n; // Initialize the Intrinsics shell = XtAppInitialize (&app, "Hello", NULL, 0, &argc, argv, NULL, NULL, 0 );

...

Page 5: A Simple Motif Widget The basic steps involved in creating and displaying this or any other Motif widget are essentially the same. This is a shell widget

Notes on the First Part

All include files are relative to /usr/include/ Xm/Xm.h includes X11/Intrinsic.h and X11/Xlib.h

Xm.h defines Motif widgets (names start with ``Xm'') Intrinsic.h defines X Toolkit widgets (names

start with ``Xt'') Xlib.h defines X basics (names start with ``X'') The call to XtAppInitialize combines steps 1

and 2

Page 6: A Simple Motif Widget The basic steps involved in creating and displaying this or any other Motif widget are essentially the same. This is a shell widget

"Hello World" Program (cont'd) ... // Create a compound string to display the Hello message xmstr = XmStringCreateLocalized ( "Hello World" ); // Create a label widget to display the string n = 0; XtSetArg ( args[n], XmNlabelString, xmstr ); n++; label = XtCreateManagedWidget ( "label", xmLabelWidgetClass,

shell, args, n ); // Free the compound string when it is no longer needed XmStringFree ( xmstr ); XtRealizeWidget ( shell );

XtAppMainLoop ( app ); }

Page 7: A Simple Motif Widget The basic steps involved in creating and displaying this or any other Motif widget are essentially the same. This is a shell widget

Notes on the Second Part

The call to XtCreateManagedWidget combines steps 3 and 5

There is no step 4 in this example (no ``callbacks'')

The call to XtRealizeWidget is step 6 The call to XtAppMainLoop is step 7

Page 8: A Simple Motif Widget The basic steps involved in creating and displaying this or any other Motif widget are essentially the same. This is a shell widget

Initialization (Steps 1 and 2)

Xt initialization function prototype:

Widget XtAppInitialize ( XtAppContext *appContext, //1 const String className, //2 XrmOptionDescList options, //3 Cardinal numOptions, //4 Cardinal *argc, //5 char **argv, //6 const String *fallbackResources, //7 ArgList args, //8 Cardinal numArgs ); //9

XtAppInitialize is a convenience function.

Page 9: A Simple Motif Widget The basic steps involved in creating and displaying this or any other Motif widget are essentially the same. This is a shell widget

XtAppInitialize Arguments

1 Reference argument to hold application context data structure

2 Application's class name, which is usually the program name upper cased

3 Used if application-specific command line arguments are allowed by the application

4 ditto

5 Used to search for standard command line args

6 ditto

Page 10: A Simple Motif Widget The basic steps involved in creating and displaying this or any other Motif widget are essentially the same. This is a shell widget

XtAppInitialize Arguments (cont'd)

7 Used if additional customizable widget parameters (resources) are required as fallbacks

8 Allows the program to specify additional arguments (not the user) to be passed to the shell widget

9 ditto

Page 11: A Simple Motif Widget The basic steps involved in creating and displaying this or any other Motif widget are essentially the same. This is a shell widget

Compound Strings

Motif has defined an abstraction called compound string to allow for international character sets and eliminate dependency on ASCII

The easiest way to create a Motif compound string is with XmStringCreateLocalized:

xmstr = XmStringCreateLocalized("Hello World");

Page 12: A Simple Motif Widget The basic steps involved in creating and displaying this or any other Motif widget are essentially the same. This is a shell widget

Creating Widgets (Step 3)

The simplest way to create a widget (prototype):

Widget XtCreateWidget (const String name, //1 WidgetClass widgetclass, //2 Widget parent, //3 ArgList args, //4 Cardinal numArgs ); //5

Page 13: A Simple Motif Widget The basic steps involved in creating and displaying this or any other Motif widget are essentially the same. This is a shell widget

XtCreateWidget Arguments

1 Name of the widget to be created (in our example, "label")

2 Class pointer for the widget (xmLabelWidgetClass)

3 Parent of the new widget (in our example, "shell")

4 To specify additional widget arguments

5 ditto

Page 14: A Simple Motif Widget The basic steps involved in creating and displaying this or any other Motif widget are essentially the same. This is a shell widget

Managing Widgets (Step 5)

Every widget except the shell must be managed by its parent

After creating a widget with XtCreateWidget, you can manage it with another Xt call (XtManageChild)

Or, you can do it all at once with XtCreateManagedWidget, which accepts the same arguments as XtCreateWidget.

Page 15: A Simple Motif Widget The basic steps involved in creating and displaying this or any other Motif widget are essentially the same. This is a shell widget

Giving Widgets Additional Info

The first 3 arguments to XtCreateWidget (or XtCreateManagedWidget) are required for every widget class

However, different widget classes have different parameters associated with them (called resources).

For example, a label widget cannot be created without a string that it is to display

Specific widget resources are passed to XtCreateWidget through an ArgList.

Page 16: A Simple Motif Widget The basic steps involved in creating and displaying this or any other Motif widget are essentially the same. This is a shell widget

Giving Widgets Additional Info (cont'd)

An ArgList is an array of type Arg An Arg is a pair consisting of the name of a widget's

customizable parameter and also the value of the parameter

In our example, name: XmNlabelString value: Motif string "Hello World"

It is often convenient to use the macro XtSetArg to add a name/value pair to an ArgList.

Page 17: A Simple Motif Widget The basic steps involved in creating and displaying this or any other Motif widget are essentially the same. This is a shell widget

Using XtSetArg

In our example:

Arg args[10];int n; . . .n = 0;XtSetArg ( args[n], XmNlabelString, xmstr );n++;label = XtCreateManagedWidget("label", XmLabelWidgetClass, shell, args, n );

To find widget resource names and widget class pointers, consult the online Motif reference sheet.

0 . . . 9

args

Page 18: A Simple Motif Widget The basic steps involved in creating and displaying this or any other Motif widget are essentially the same. This is a shell widget

Another Example

We can also specify the width and height of thelabel in pixels:

Arg args[10];int n; . . .n = 0;XtSetArg ( args[n], XmNlabelString, xmstr ); n++;XtSetArg ( args[n], XmNwidth, 400 ); n++;XtSetArg ( args[n], XmNheight, 300 ); n++;

label = XtCreateManagedWidget("label", XmLabelWidgetClass, shell, args, n );

0 1 2 . . . 9

args

Page 19: A Simple Motif Widget The basic steps involved in creating and displaying this or any other Motif widget are essentially the same. This is a shell widget

New Larger Label Widget

Note: Font sizes are usually specified using the X Resource Manager and Database, covered later.

Also, the look-and-feel of the frame surrounding thewidget is different because a different window manager was used.

Page 20: A Simple Motif Widget The basic steps involved in creating and displaying this or any other Motif widget are essentially the same. This is a shell widget

Creating Widgets Using the vararg Version

label = XtVaCreateManagedWidget ( ``label'', xmLabelWidgetClass, shell, XmNlabelString, xmstr, XmNwidth, 200, XmNheight, 300, NULL );

Page 21: A Simple Motif Widget The basic steps involved in creating and displaying this or any other Motif widget are essentially the same. This is a shell widget

Notes on XtVaCreateManagedWidget

Note the Va in the name First three arguments the same as before After that come resource/value pairs The list of pairs must be terminated with NULL

Page 22: A Simple Motif Widget The basic steps involved in creating and displaying this or any other Motif widget are essentially the same. This is a shell widget

Using XtVaSetValues To Separate Widget Creation from

Setting Widget Resource Values

label = XtVaCreateManagedWidget ( ``label'', xmLabelWidgetClass, shell, NULL);XtVaSetValues(label, XmNlabelString, xmstr, XmNwidth, 200, XmNheight, 300, NULL );

Page 23: A Simple Motif Widget The basic steps involved in creating and displaying this or any other Motif widget are essentially the same. This is a shell widget

Realizing Widgets (Step 6)

Before a widget can be seen, it must create an X window in which to display itself (called realizing the widget)

Use XtRealizeWidget for this:

void XtRealizeWidget ( Widget w );

XtRealizeWidget recursively realizes its argument and all children. In the example:

XtRealizeWidget ( shell );

Page 24: A Simple Motif Widget The basic steps involved in creating and displaying this or any other Motif widget are essentially the same. This is a shell widget

Entering the Event Loop (Step 7)

Xt implements the event loop like this:

void XtAppMainLoop ( XtAppContext app ) { for ( ; ; ) { Xevent event; XtAppNextEvent ( app, &event ); XtDispatchEvent ( &event ); }}

Page 25: A Simple Motif Widget The basic steps involved in creating and displaying this or any other Motif widget are essentially the same. This is a shell widget

Notes On The Event Loop The event loop has no explicit return XtAppNextEvent waits until an event is

available in the application's event queue

When one or more events are available, it removes the first event and returns

XtDispatchEvent finds the window in which the event occurred and sends the event to that window's widget (a callback)

Starting the event loop in the example:

XtAppMainLoop( app );

Page 26: A Simple Motif Widget The basic steps involved in creating and displaying this or any other Motif widget are essentially the same. This is a shell widget

Compiling and Running hello.C

12% g++ -o hello hello.C -lXm -lXt -lX1113% hello

The widget will be displayed in the upper left handcorner of the screen.

The "hello" program will not terminate until the userclicks the menu bar and quits the widget.

Load libraries must be specified using -l option.

Page 27: A Simple Motif Widget The basic steps involved in creating and displaying this or any other Motif widget are essentially the same. This is a shell widget

Handling Events

A widget with a pushbutton instead of a label:

Note that the widget is shaded in such as way as tomake it appear to protrude from the screen.

Suppose we want this application to quit when the "Push Me" button is clicked.

Page 28: A Simple Motif Widget The basic steps involved in creating and displaying this or any other Motif widget are essentially the same. This is a shell widget

Callback Functions Each widget supports a specified set of callbacks,

which trigger functions to be called when certain events are detected by the widget

There are three types of callbacks for the pushbutton widget:

1 XmNarmCallback: when mouse button is clicked while mouse cursor is on button

2 XmNactivateCallback: when mouse button is released while mouse cursor is on button

3 XmNdisarmCallback: when mouse button is released after mouse cursor moves off button

Callbacks for all widgets are in reference sheet.

Page 29: A Simple Motif Widget The basic steps involved in creating and displaying this or any other Motif widget are essentially the same. This is a shell widget

Associating a Function with a Callback

1 The widget to be associated with the callback

2 Name of the callback

3 The actual callback function

4 Optional application-defined data to be passed to the callback function when called

void XtAddCallback (Widget widget, //1const String callbackName, //2XtCallbackProc proc, //3XtPointer clientData); //4

Page 30: A Simple Motif Widget The basic steps involved in creating and displaying this or any other Motif widget are essentially the same. This is a shell widget

Prototype of a Callback Function

This is the function called by the X server back to the client application. It passes the following information back to the client:

1 The widget for which the callback was called

2 The clientData specified by the client application in the call to XtAddCallback.

3 Data provided by the widget, usually concerning the nature of the X event that triggered the callback

void <funcname> (Widget w, // 1 XtPointer clientData, // 2 XtPointer callData); // 3

Page 31: A Simple Motif Widget The basic steps involved in creating and displaying this or any other Motif widget are essentially the same. This is a shell widget

A Simple Callback that Quits

Note that a simple callback like this does not use its parameters

To avoid compiler warnings about unused parameters, leave the parameter type but omit names:

void quitCallback (Widget, XtPointer, XtPointer) ...

void quitCallback (Widget w, XtPointer clientData, XtPointer callData) {

exit ( 0 );}

Page 32: A Simple Motif Widget The basic steps involved in creating and displaying this or any other Motif widget are essentially the same. This is a shell widget

Pushbutton Example

// pushme.C, Using callback functions in C++#include <stdlib.h> // Needed for exit prototype#include <Xm/Xm.h>#include <Xm/PushB.h>

static void quitCallback ( Widget, XtPointer, XtPointer );

void main ( int argc, char **argv ){ Widget button, shell; XtAppContext app; XmString xmstr; // Initialize the Intrinsics shell = XtAppInitialize ( &app, "Pushme", NULL, 0,

&argc, argv, NULL, NULL, 0 ); ...

Page 33: A Simple Motif Widget The basic steps involved in creating and displaying this or any other Motif widget are essentially the same. This is a shell widget

Pushbutton Example (cont'd)

. . . // Create a compound string xmstr = XmStringCreateLocalized ( "Push Me" ); // Create an XmPushButton widget to display the string button = XtVaCreateManagedWidget ( "button",

xmPushButtonWidgetClass, shell, XmNlabelString, xmstr, NULL );

// Free the compound string after the XmPushButton // has copied it XmStringFree ( xmstr ); ...

Page 34: A Simple Motif Widget The basic steps involved in creating and displaying this or any other Motif widget are essentially the same. This is a shell widget

Pushbutton Example (cont'd) . . . // Register the quitCallback callback function // to be called when the button is pushed XtAddCallback ( button,

XmNactivateCallback, quitCallback, NULL ); // No client data needed

// Realize all widgets and enter the main event loop XtRealizeWidget ( shell ); XtAppMainLoop ( app );}

// Callback invoked when button is activated void quitCallback ( Widget, XtPointer, XtPointer ) { exit ( 0 ); }

Page 35: A Simple Motif Widget The basic steps involved in creating and displaying this or any other Motif widget are essentially the same. This is a shell widget

Notes on the Pushbutton Example

Includes a different widget header file (Xm/PushB.h)

Incorporates the quitCallback prototype Has a call to XtAddCallback Defines the quitCallback function

Page 36: A Simple Motif Widget The basic steps involved in creating and displaying this or any other Motif widget are essentially the same. This is a shell widget

The Architectural Impact of Event Driven Programming

Applications run asynchronously with respect to the server (and with respect to other applications)

Program cannot suspend while waiting for input (as with scanf), because it cannot receive events

No user-friendly way to interrupt an application (control-C will not work)

A program task should not take longer than the user's perception of a "reasonable" response time

If a task is not done quickly, events will pile up in the queue and the user will encounter windows not redrawn correctly (or worse)