Xlib
Interaction with the X Window System can be achieved by using the Xlib interface fortran-xlib for Fortran 2003. Creating windows using raw Xlib works on all systems that have an X server running.
A widget toolkit, like Motif, GTK, Qt, or Tk, is not required, albeit no visual components (buttons, labels, menus, …) are part of the Xlib standard. As a consequence, programmers only have access to simple drawing functions for text, geometric shapes, and images. The Motif or GTK bindings for Fortran can be used instead to facilitate the implementation of full-featured graphical user interfaces.
- Fig. 1: The example X11 program written in Fortran 2003
Xlib programming in Fortran does not differ significantly from one in other
languages, as xlib.f90
is solely an ISO C binding interface.
fortran-xlib
Clone the GitHub repository and simply run make
to build the
static library libfortran-xlib.a
:
$ git clone https://github.com/interkosmos/fortran-xlib
$ cd fortran-xlib/
$ make
Link your Fortran application with libfortran-xlib.a -lX11
and
the fortran-xlib module files.
Example
The program draws some text and fills a rectangle (fig. 1) on the root
window. The X application xfontsel(1) lets us select an X font name
string (other than -*-helvetica-bold-r-*-*-14-*-*-*-*-*-*-*
used in
the example). The colour name may be changed to any valid
X11 colour specifier.
! demo.f90
program main
use, intrinsic :: iso_c_binding
use :: xlib
implicit none
integer, parameter :: WIDTH = 320 ! Window width.
integer, parameter :: HEIGHT = 200 ! Window height.
character(len=*), parameter :: TITLE = 'Fortran X11' ! Window title.
character(len=*), parameter :: COLOR_NAME = 'Sea Green' ! X11 colour name.
character(len=*), parameter :: FONT_NAME = '-*-helvetica-bold-r-*-*-14-*-*-*-*-*-*-*'
character(len=32) :: str
integer :: direction, ascent, descent
integer :: rc, screen, x, y
integer(kind=c_long) :: black, white
integer(kind=c_long) :: colormap, wm_delete_window
integer(kind=c_long) :: long(5)
integer(kind=c_long) :: root, window
type(c_ptr) :: display, gc
type(x_char_struct) :: overall
type(x_color) :: color
type(x_event) :: event
type(x_font_struct) :: font
type(x_gc_values) :: values
type(x_size_hints) :: size_hints
! Open display.
display = x_open_display(c_null_char)
screen = x_default_screen(display)
root = x_default_root_window(display)
colormap = x_default_colormap(display, screen)
! Define colours.
black = x_black_pixel(display, screen)
white = x_white_pixel(display, screen)
rc = x_alloc_named_color(display, &
colormap, &
COLOR_NAME // c_null_char, &
color, &
color)
! Create window.
window = x_create_simple_window(display, root, 0, 0, WIDTH, HEIGHT, 0, black, white)
call x_store_name(display, window, TITLE // c_null_char)
! Register closing of window.
wm_delete_window = x_intern_atom(display, &
'WM_DELETE_WINDOW' // c_null_char, &
.false._c_bool)
rc = x_set_wm_protocols(display, window, wm_delete_window, 1)
! Set hints to prevent resizing.
size_hints%flags = ior(P_MIN_SIZE, P_MAX_SIZE)
size_hints%min_width = WIDTH
size_hints%min_height = HEIGHT
size_hints%max_width = WIDTH
size_hints%max_height = HEIGHT
call x_set_wm_normal_hints(display, window, size_hints)
! Create graphics context.
gc = x_create_gc(display, window, 0_c_long, values)
! Load and set font.
font = x_load_query_font(display, FONT_NAME // c_null_char)
call x_set_font(display, gc, font%fid)
! Show window.
call x_select_input(display, window, ior(EXPOSURE_MASK, STRUCTURE_NOTIFY_MASK))
call x_map_window(display, window)
! Set text and text position.
str = 'X11 window with Fortran'; x = 25; y = 25
! Event loop.
do
call x_next_event(display, event)
select case (event%type)
case (EXPOSE)
! Redraw the window.
call x_text_extents(font, string, len_trim(str), direction, ascent, descent, overall)
call x_set_foreground(display, gc, color%pixel) ! Set colour.
call x_draw_string(display, window, gc, x, y, str, len_trim(str)) ! Draw text.
call x_fill_rectangle(display, window, gc, x, y + 25, 100, 100) ! Fill rectangle.
case (CLIENT_MESSAGE)
! Quit if window is closed.
long = transfer(event%x_client_message%data, long)
if (long(1) == wm_delete_window) exit
end select
end do
! Clean up and quit.
call x_free_colors(display, colormap, [ color%pixel ], 1, 0_c_long)
call x_free_gc(display, gc)
call x_destroy_window(display, window)
call x_close_display(display)
end program main
Link the example program with libfortran-xlib.a -lX11
:
$ gfortran13 -I/usr/local/include -L/usr/local/lib -o demo demo.f90 libfortran-xlib.a -lX11
$ ./demo
For further examples, see the fortran-xlib source code repository.
Fortran Libaries
- fortran-xlib: Fortran 2003 interface bindings to Xlib
References
- The Open Group: Xlib C Language X Interface (PDF)
< EGGX/ProCALL | [Index] | Motif > |