Motif

Motif (Xm) is an widget toolkit for Unix, Linux, Cygwin, and other platforms, used to create graphical user interfaces (fig. 1). Once the standard widget library on commercial UNIX systems, and used by the CDE and IRIX desktop environments, it has now become quite dated. In 2012, the source code was released as Open Motif under GNU LGPL.

The fortran-motif library is a collection of Fortran 2008 interface bindings, providing access to Motif, and, optionally, to the XmHTML widget.

fortran-motif
Fig. 1: Motif application written in Fortran 2008, using fortran-motif

fortran-motif

The Motif toolkit has to be present on the system. On FreeBSD, install Open Motif with:

# pkg install x11-toolkits/open-motif

On Linux, additional development headers may be required. Download and compile fortran-motif with:

$ git clone https://github.com/interkosmos/fortran-motif
$ cd fortran-motif/
$ make PREFIX=/usr/local

Link your Fortran application against the static library libfortran-motif.a and -lXm -lXt -lX11.

Example

The example program just opens a window by calling the X Toolkit Intrinsics (Xt), and displays a string inside an XmLabel widget:

! demo.f90
program main
    use, intrinsic :: iso_c_binding
    use :: xm
    use :: xt
    implicit none
    integer, parameter :: WINDOW_HEIGHT = 300
    integer, parameter :: WINDOW_WIDTH  = 400

    character(len=16), target :: window_title = 'Fortran + Motif' // c_null_char
    type(c_ptr)               :: app_ptr
    type(c_ptr)               :: form_ptr
    type(c_ptr)               :: label_ptr
    type(c_ptr)               :: str_ptr
    type(c_ptr)               :: window_ptr
    type(xt_arg),      target :: args(3)

    ! Create Xt window.
    call xt_set_arg(args(1), XM_N_TITLE,  c_loc(window_title))
    call xt_set_arg(args(2), XM_N_HEIGHT, WINDOW_HEIGHT)
    call xt_set_arg(args(3), XM_N_WIDTH,  WINDOW_WIDTH)

    window_ptr = xt_open_application(app_ptr, &                         ! Application context.
                                     'FortranApp' // c_null_char, &     ! Class name of this application.
                                     c_null_ptr, &                      ! Options description.
                                     0, &                               ! Number of entries in the options list.
                                     0, &                               ! Number of command-line parameters.
                                     c_null_ptr, &                      ! Command-line parameters.
                                     c_null_ptr, &                      ! Fallback resources.
                                     APPLICATION_SHELL_WIDGET_CLASS, &  ! Widget class.
                                     c_loc(args), &                     ! Argument list.
                                     3)                                 ! Number of arguments in argument list.

    ! Create XmForm widget.
    call xt_set_arg(args(1), XM_N_MARGIN_HEIGHT, 25)
    call xt_set_arg(args(2), XM_N_MARGIN_WIDTH,  25)

    form_ptr = xt_create_managed_widget('Form' // c_null_char, &        ! Class name.
                                         XM_FORM_WIDGET_CLASS, &        ! Widget class.
                                         window_ptr, &                  ! Parent.
                                         c_loc(args), &                 ! Argument list.
                                         2)                             ! Number of entries in argument list.

    ! Create XmLabel widget.
    str_ptr = xm_string_create_localized('Hello, World!' // c_null_char)

    call xt_set_arg(args(1), XM_N_LABEL_STRING,    str_ptr)
    call xt_set_arg(args(2), XM_N_LEFT_ATTACHMENT, XM_ATTACH_FORM)
    call xt_set_arg(args(3), XM_N_TOP_ATTACHMENT,  XM_ATTACH_FORM)

    label_ptr = xt_create_managed_widget('Label' // c_null_char, &      ! Class name.
                                         XM_LABEL_WIDGET_CLASS, &       ! Widget class.
                                         form_ptr, &                    ! Parent.
                                         c_loc(args), &                 ! Argument list.
                                         3)                             ! Number of entries in argument list.
    call xm_string_free(str_ptr)

    ! Show window and run main loop.
    call xt_realize_widget(window_ptr)
    call xt_app_main_loop(app_ptr)
end program main

Compile and run the demo application with:

$ gfortran10 -I/usr/local/include/ -L/usr/local/lib/ \
  -o demo demo.f90 libfortran-motif.a -lXm -lXt -lX11
$ ./demo

Further examples are included in the fortran-motif source code repository.

References