Guide

Getting Started

IUP has four important concepts that are implemented in a very different way from other toolkits.

First is the control creation timeline. When a control is created it is not immediately mapped to the native system. So some attributes will not work until the control is mapped. The mapping is done when the dialog is shown or manually calling IupMap for the dialog. You can not map a control without inserting it into a dialog.

Second is the attribute system. IUP has only a few functions because it uses string attributes to access the properties of each control. So get used to IupSetAttribute and IupGetAttribute, because you are going to use them a lot.

Third is the abstract layout positioning. IUP controls are never positioned in a specific (x,y) coordinate inside the dialog. The positioning is always calculated dynamically from the abstract layout hierarchy. So get used to the IupFill, IupHbox and IupVbox controls that allows you to position the controls in the dialog.

Fourth is the callback system. Because of the LED resource files IUP has an indirect form to associate a callback to a control. You associate a C function with a name using IupSetFunction, and then associate the callback attribute with that name using IupSetAttribute. But applications now should use the IupSetCallback function to directly associate a callback for a control. 

LED is the original IUP resource file which has been replaced in favor of Lua files, although it is still supported. But keep in mind that you can use IUP without using LED or Lua, by just using the C API.

Building Applications

To compile programs in C, simply include file iup.h. If the application only uses functions from IUP and other cross-platform libraries that have the same API in all platforms, then the application immediately becomes platform independent. The implementation of the IUP functions is different in each platform and the linker is in charge of solving the IUP functions using the library specified in the project/makefile. For further information on how to link your application, please refer to the specific driver documentation.

IUP can also work together with other interface toolkits. The main problem is the IupMainLoop function. If you are going to use only Popup dialogs, then it is very simple. But to use non modal dialogs without the IupMainLoop you must call IupLoopStep from inside your own message loop. Also it is not possible to use Iup controls with dialogs from other toolkits and vice-versa.

The generation of applications is highly dependent on each system, but at least the iup library must be linked.

To use the additional controls you will need the iupcontrols and iupcd libraries and the CD library cd.

Other controls are available in secondary libraries, they also may have other external dependencies, check the documentation of the control.

If you are using IUP libraries in Windows DLLs or in Posix SOs dynamic libraries, then it is not necessary to worry about secondary dependencies, only specify the libraries you directly use. If you link to the static libraries then you must include all the secondary dependencies.

To use the Lua Binding, you need to link the program with the iuplua library and with the lua library. The other secondary libraries also have their Lua binding libraries that must be linked to use the control in Lua.

The download files list includes the Tecgraf/PUC-Rio Library Download Tips document, with a description of all the available binaries.

Windows

For Windows, if you statically link the application with IUP you must link also with the libraries ole32.lib and comctl32.lib (provided with the compilers). The iup.rc resource file (or a custom version) should be included in the application's project/makefile so that some icons and cursors can be used when not using the DLLs and to enable Windows Visual Styles. iup.rc is located in "/etc" folder of the distribution.

There is also guides for using some IDEs: C++ Builder XDev-C++ OpenWatcom C++, Visual C++ 7 (Visual Studio 2003), Visual C++ 8 (Visual Studio 2005), CodeLite, Code Blocks, NetBeans and Eclipse for C++.

In Windows, when using Gcc to link an application the libraries order are as important as in UNIX. Always put the less dependent library at the end, for example:

-liup -lgdi32 -lcomdlg32 -lcomctl32 -luuid -loleaut32 -lole32

See more information in the Windows System Driver.

Motif

For Motif, IUP uses the Motif (Xm), the Xtoolkit (Xt) and the Xlib (X11) libraries. To statically link an application with IUP, use the following options in the linker call (in the same order):

-liup -lXm -lXmu -lXt -lX11 -lm

Though these are the minimum requirements, depending on the platform other libraries might be needed. Typically, they are X extensions (Xext), needed in SunOS, and Xpm (needed in Linux only). They must be listed after Xt and before X11. For instance:

-liup -lXm -lXpm -lXmu -lXt -lXext -lX11 -lm

Usually these libraries are placed in default directories, but you may require additional options:

Linux -L/usr/X11R6/lib -I/usr/X11R6/include
IRIX -L/usr/lib32 (X11)
-L/usr/Motif-2.1/lib32 -I/usr/Motif-2.1/include (Motif)
SunOS -L/usr/openwin/lib -I/usr/openwin/share/include (X11)
-L/usr/dt/lib -I/usr/dt/share/include (Motif)

See more information in the Motif System Driver.

GTK+ (since IUP 3.0)

For GTK, IUP uses the GTK, GDK, Pango, Cairo if GTK 3, and GLib. To statically link an application with IUP, use the following options in the linker call (in the same order):

-lgtk-x11-2.0 -lgdk-x11-2.0 -lgdk_pixbuf-2.0 -lpangox-1.0 -lpango-1.0 -lgobject-2.0 -lgmodule-2.0 -lglib-2.0 -lXext -lX11 -lm  (for GTK 2)
or
-lgtk-3 gdk-3 -lgdk_pixbuf-2.0 -lpangocairo-1.0 -lpango-1.0 -lcairo   -lgobject-2.0 -lgmodule-2.0 -lglib-2.0 -lXext -lX11 -lm  (for GTK 3)

 A simpler way to obtain GTK parameters for static linking is to use the pkg-config tool:

LIBS += $(shell pkg-config --libs gtk+-2.0 gdk-2.0)

See more information in the GTK System Driver.

Multithread

User interface is usually not thread safe and IUP is not thread safe. The general recommendation when you want more than one thread is to build the application and the user interface in the main thread, and create secondary threads that communicates with the main thread to update the interface. The secondary threads should not directly update the interface.

Dynamic Loading

Although we have dynamic libraries we do not recommend the dynamic loading of the main IUP library in Motif. This is because it depends on Motif and X11, you will have to load these libraries first. So it is easier to build a base application that already includes X11, Motif and the main IUP library than trying to load them all. In Windows this is not a problem.

The IUP secondary libraries can be easily dynamic loaded regardless of the system.

Building The Library

In the Downloads you will be able to find pre-compiled binaries for many platforms, all those binaries were built using Tecmake. Tecmake is a command line multi compiler build tool based on GNU make, available at http://www.tecgraf.puc-rio.br/tecmake. Tecmake is used by all the Tecgraf libraries and many applications.

You do not need to install Tecmake, scripts for Posix and Windows systems are already included in the source code package. Just type "make" in the command line on the main folder and all libraries and executables will be build.

In Linux, check the "Building Lua, IM, CD and IUP in Linux" guide.

In Windows, check the "Building Lua, IM, CD and IUP in Window" guide.

If you decide to install Tecmake, the Tecmake configuration files (*.mak) are available at the "src*" folders, and are very easy to understand. In the main folder, and in each source folder, there are files named make_uname.bat that build the libraries using Tecmake. To build for Windows using Visual C 9.0 (2008) for example, just execute "make_uname vc9" in the iup main folder, or for the DLLs type "make_uname dll9". The Visual Studio workspaces with the respective projects available in the source package is for debugging purposes only.

IUP runs on many different systems and interact with many different libraries such as Motif, OpenGL, Canvas Draw (CD) and Lua. You have to install some these libraries to build the secondary IUP libraries. Make sure you have all the dependencies for the library you want installed, see the documentation below.

If you are going to build all the libraries, the makefiles and projects expect the following directory tree:

/mylibs/
        iup/
        cd/
        im/
        lua5.1/

To control that location set the TECTOOLS_HOME environment variable to the folder were the CD, IM and Lua libraries are installed.

IUP_ASSERT can be defined to enable some runtime checks for the main API.

File Encoding

Almost all IUP source code files are in pure ASCii encoding. But some files are encoded in ISO8859-1 and some in UTF-8 where Portuguese and Spanish strings are written.

This occurs in a few source files only. If you have trouble compiling these source files you can convert the strings to contain pure ASCii characters using an Hexadecimal representation of the non ASCii characters, for instance: "Atenção!" will be "Aten\xE7\xE3o!". You can use the Lua script convert2ascii.lua to do that. The following files will be affected:

src/iup_lng*.h
srccontrols/matrixex/iup_lng*.h
srcplot/iup_lng*.h

Notice that the UTF-8 strings will also be correct using the Hexadecimal representation.

Libraries Dependencies

iupwin* -> gdi32 user32 comdlg32 comctl32 uuid ole32 (system - Windows)
iupmot* -> [Xpm Xmu Xext] Xt X11 (system - UNIX)
iupgtk* -> gtk-win32-2.0 gdk-win32-2.0 pangowin32-1.0(system - Windows)
        -> gtk-x11-2.0 gdk-x11-2.0 pangox-1.0 (system - UNIX)
        -> gdk_pixbuf-2.0 pango-1.0 gobject-2.0 gmodule-2.0 glib-2.0 (system - Windows/UNIX)
iupgl -> iup
      -> opengl32 glu32 glaux (system - Windows)
      -> GLU GL (system - UNIX)
iupcd -> iup
      -> cd
iupcontrols -> iupcd
iup_plot -> iupcd
iupim -> iup
      -> im
iupimglib -> iup
iuplua51 -> iup
         -> lua5.1
iupluacd51 -> iuplua51
           -> cdlua51
           -> iupcd
iupluacontrols51 -> iuplua51
                 -> iupcontrols
iupluagl51 -> iuplua51
           -> iupgl
iupluaim51 -> iuplua51
           -> imlua51
           -> iupim
iupluaole51 -> iuplua51
           -> iupole
iuplua_plot51 -> iuplua51
               -> iup_plot
iupole -> iup
iupweb -> iupole (Windows)
       -> webkit-1.0 (Linux)

(*) In Windows, "iupwin" is called "iup". 
    In Linux and BSD "iupgtk" is called "iup". 
    In IRIX, AIX and SunOS "iupmot" is called "iup".

As a general rule (excluding system dependencies): IUP depends on CD and IM, and IUPLua depends on Lua, CDLua and IMLua. Notice that not all IUP libraries depend on CD and IM.

Instead of building all the libraries, try building only the libraries you are going to use. The Makefile on the root folder will build all the libraries, but in each source folder there are secondary Makefiles. We use the following source code structure:

iup/
    src/           - The core library. Motif, GTK and Windows code
    srccd/         - CD_IUP canvas driver for the CD library
    srccontrols/   - IupControls additional controls - IupMatrix, IupMatrixEx, IupMatrixList, IupCells
    srcgl/         - IupGLCanvas
    srcglcontrols/ - IupGLControls additional OpenGL controls 
    srcim/         - IUP/IM utilities
    srcimglib/     - Image Libraries with Icons, Logos and Bitmaps
    srclua5/       - Lua 5 binding
    srcole/        - IupOleControl
    srcplot/       - IupPlot
    srcscintilla/  - IupScintilla
    srctuio/       - IupTuioClient
    srcweb/        - IupWebBrowser

The Lua bindings for IUP, CD and IM (Makefiles and Pre-compiled binaries) depend on the LuaBinaries distribution. So if you are going to build from source, then use the LuaBinaries source package also, not the Lua.org original source package. If you like to use another location for the Lua files define LUA_SUFFIX, LUA_INC, LUA_LIB and LUA_BIN before using Tecmake.

In Ubuntu you will need to install the following packages and their dependencies (they are not installed by default):

libgtk2.0-dev (for the GTK driver)
or
libgtk3.0-dev (for the GTK driver) 
    libmotif-dev and x11proto-print-dev (for the Motif driver, if used)
libgl1-mesa-dev and libglu1-mesa-dev (for the IupGLCanvas)
libwebkitgtk-dev (for the IupWebBrowser)
or
libwebkitgtk3.0-dev (for the IupWebBrowser)

Using IUP in C++

IUP is a low level API, but at the same time a very simple and intuitive API. That's why it is implemented in C, to keep the API simple. But most of the actual IUP applications today use C++. To use C callbacks in C++ classes, you can declare the callbacks as static members or friend functions, and store the pointer "this" at the "Ihandle*" pointer as an user attribute. For example, you can create your dialog by inheriting from the following dialog.

class iupDialog
{
private:
  Ihandle *hDlg;
  int test;

  static int ResizeCB (Ihandle* self, int w, int h); 
  friend int ShowCB(Ihandle *self, int mode); 

public:
  iupDialog(Ihandle* child)
  { 
    hDlg = IupDialog(child); 
    IupSetAttribute(hDlg, "iupDialog", (char*)this); 
    IupSetCallback(hDlg, "RESIZE_CB", (Icallback)ResizeCB);
    IupSetCallback(hDlg, "SHOW_CB", (Icallback)ShowCB);
  }

  void ShowXY(int x, int y) { IupShowXY(hDlg, x, y); }

protected:

  // implement this to use your own callbacks
  virtual void Show(int mode) {};
  virtual void Resize (int w, int h){}; 
};

int iupDialog::ResizeCB(Ihandle *self, int w, int h)
{
  iupDialog *d = (iupDialog*)IupGetAttribute(self, "iupDialog");
  d->test = 1; // private members can be accessed in private static members
  d->Resize(w, h);
  return IUP_DEFAULT;
}

int ShowCB(Ihandle *self, int mode)
{
  iupDialog *d = (iupDialog*)IupGetAttribute(self, "iupDialog");
  d->test = 1; // private members can be accessed in private friend functions
  d->Show(mode);
  return IUP_DEFAULT;
}

This is just one possibility on how to write a wrapper class around IUP functions. Some users contributed with C++ wrappers, see next on Contributions.

To help the creation of callbacks as methods in C++ Classes we provide (since 3.15) a header file called "iup_class_cbs.hpp" that has some macros for that usage. There are 3 macros that need to be called:

IUP_CLASS_INITCALLBACK(ih, class) - to register the object as a callback receiver 
                                    (called only once for a dialog, usually in the constructor, but can be called for children)
                                    (it can be called several times with the same class name to handle more than one dialog)
IUP_CLASS_SETCALLBACK(ih, name, function)  - to associate the callback for a given element
IUP_CLASS_DECLARECALLBACK_IFn*(class, function) - to declare the callback as a member function 
                                    (defined as the typedefs in "iupcbs.h" for all callbacks)

There is no order when calling the macros. The function name must match in SETCALLBACK and DECLARECALLBAK or it will not work. The class name must match in INITCALLBACK and DECLARECALLBAK or it will not work. The macros will not work for a hierarchy of classes, all 3 macros must be set on the same class. For a class that inherits from another class where the macros where use, the macros must be called again and they will not affect the inherited class behavior.

This allows an application to define callbacks as methods of any class it is using in the application. The method will have exactly the same definition as the callback. And it will not be a static method, so there will be no need to access a pointer to the this object. Here is an example:

class SampleClass
{
  int sample_count;

public:
  SampleClass()
  {
    sample_count = 0;

    Ihandle* button1 = IupButton("Inc", NULL);
    Ihandle* button2 = IupButton("Dec", NULL);
    Ihandle* dialog = IupDialog(IupHbox(button1, button2, NULL));

    // 1) Register "this" object as a callback receiver (needed only once for the dialog)
    IUP_CLASS_INITCALLBACK(dialog, SampleClass);

    // 2) Associate the callback with the button
    IUP_CLASS_SETCALLBACK(button1, "ACTION", ButtonAction1);
    IUP_CLASS_SETCALLBACK(button2, "ACTION", ButtonAction2);

    IupShow(dialog);
  };

protected:
  // 3) Declare the callback as a member function
  IUP_CLASS_DECLARECALLBACK_IFn(SampleClass, ButtonAction1);
  IUP_CLASS_DECLARECALLBACK_IFn(SampleClass, ButtonAction2);
};

// 4) Define the callback as a member function
int SampleClass::ButtonAction1(Ihandle*)
{
  sample_count++;
  return IUP_DEFAULT;
}

int SampleClass::ButtonAction2(Ihandle*)
{
  sample_count--;
  return IUP_DEFAULT;
}

Memory Checking

Periodically we run some tool to check for memory usage and check for leaks or other misuse.

In Windows we use Visual Leak Detector (https://kinddragon.github.io/vld/). You just have to include this in your code once:

 #ifdef WIN32
#define VLD_MAX_DATA_DUMP 80
#include <vld.h>
#endif

For Linux we use Valgrind (http://valgrind.org/), but there are a few problems with GTK that should be ignored. We suggest the following environment variable:

export VALGRIND_OPTS="--tool=memcheck -v --leak-check=full --show-reachable=yes --num-callers=30 --leak-resolution=high --error-limit=no --suppressions=gtk.supp --track-origins=yes"

The file with the necessary suppressions can be downloaded here. Take a look at this page for more info: https://wiki.gnome.org/Valgrind.

Another free tool available for Linux and Windows is Doctor Memory (https://drmemory.org/). EletricFence is another tool for Linux (https://elinux.org/Electric_Fence).