Getting Started with Xarm

So you've compiled and installed Xarm (or maybe you're just looking ahead). Now It's time to write some code. This example will show you some of the techniques of programming with Xarm. Keep in mind that there is a variety of ways to implement an application. This example will only show you one. The files in the examples directory of the Xarm distribution will show you more. And you are likely to come up with some on your own. That's fine.


Header Files

The first thing to do is to include the proper header files, just like you do in other Motif programs. The difference is that you use the files in the Xarm directory instead of those in the Xm directory.

#include <Xarm/AppContext.h>
#include <Xarm/PushB.h>


AppContext

Xarm has a class for every Motif widget. The class hierarchy is the same as Motif's. PushButton is a subclass of Label which is a subclass of Primitive etc. As you may have noticed, Xarm also includes an AppContext class for the top level widget. Typically a class is derived from AppContext so that the callback functions can be included as methods.

class Application: public AppContext
{
  // Declare callback functions.
  void Exit(Widget, XtPointer, XtPointer);

public:
  Application(char*, int&, char**);
};

Main()

Realization of the top level widget (XtRealizeWidget) and looping for events (XtAppMainLoop) are accomplished by methods of AppContext. So main() may look as simple as this:

void main (int argc, char** argv)
{
  // Initialize the application.
  Application app(argv[0], argc, argv);

  // Realize the application.
  app.realize();

  // Start the main loop.
  app.mainLoop();
}

Widgets

The constructor of AppContext (or a derived class) is where the widgets are made and the callbacks are registered.

Application::Application(char* app_class, int& argc_in_out, char** argv_in_out):
  AppContext(app_class, 0, 0, argc_in_out, argv_in_out)
{
  PushButton* button = new PushButton("button", widget());
  button->labelString("Push Me");
  button->addCallback(button->widget(), XmNactivateCallback, (p_msg)Exit);
}

Widgets are added to the application by creating an instance of the appropriate class. In this example, button is a pointer to class PushButton, not a widget ID as returned by XmCreateWidget(). The widget ID is returned by the widget() method.

XmN resources can be set using methods of the various widget classes. Here, the resource XmNlabelString is set by button->labelString(). You can still use XtSetArg, if you wish, because the widget constructors are overloaded functions. Look at the header files for more details.


Callbacks

Callbacks are registered by the by addCallback() method. The callback is a member function of Application.

void Application::Exit(Widget wid, XtPointer client_data, XtPointer call_data)
{
  quit();
}

Compiling

You can put these code fragments together in a file and compile the program with your favorite c++ compiler. Don't forget to link in libXarm. You might use

g++ -o push_me push_me.cc -lXarm -lXm -lXt -lX11

More Information

This example program will compile and run but it lacks polish (not to mention the ability to do useful work). Also, hard-coded resources like labelString are usually considered bad form because they prevent customization and internationalization of the binaries. These subjects are beyond the scope of this simple tutorial, but here are some sources of information that will help you take full advantage of Xarm:

Remember, there's more than one way to do it.