From 115eb3270ff3039a7dcbeeb3510aa11c3a0c73d3 Mon Sep 17 00:00:00 2001
From: Adrien Destugues <pulkomandy@pulkomandy.tk>
Date: Sat, 16 Nov 2013 18:59:48 +0100
Subject: Import work done on Haiku port.


diff --git a/Makefile b/Makefile
index dac895c..3cf0b70 100644
--- a/Makefile
+++ b/Makefile
@@ -3,7 +3,7 @@ ifeq ($(OS), Windows_NT)
 endif
 
 .PHONY: do_all iup iupgtk iupmot iupcd iupcontrols iupgl iup_pplot iup_mglplot iup_scintilla iupim iupimglib ledc iupview iuplua3 iuplua5 iupconsole iupole iupweb iuptuio
-do_all: iup iupcd iupcontrols iupgl iup_pplot iup_mglplot iup_scintilla iupim iupimglib $(WINLIBS) iupweb iuptuio ledc iupview iuplua5 iupconsole
+do_all: iup iupcd iupcontrols iupgl iup_pplot iup_mglplot iupim iupimglib $(WINLIBS) iupweb iuptuio ledc iupview iuplua5 iupconsole
 
 iup iupgtk iupmot:
 	@$(MAKE) --no-print-directory -C ./src/ $@
diff --git a/src/Makefile b/src/Makefile
index b4ba247..0e099df 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -4,7 +4,7 @@ else
   TECMAKE_CMD = $(MAKE) --no-print-directory -f ../tecmake.mak
 endif
 
-.PHONY: do_all iup iupgtk iupmot iupstub
+.PHONY: do_all iup iupgtk iupmot iuphaiku iupstub
 do_all: iup
 
 iup:
@@ -16,5 +16,8 @@ iupgtk:
 iupmot:
 	@$(TECMAKE_CMD) USE_MOTIF=Yes
 
+iuphaiku:
+	@$(TECMAKE_CMD) USE_HAIKU=Yes
+
 iupstub:
 	@$(TECMAKE_CMD) MF=iupstub
diff --git a/src/config.mak b/src/config.mak
index c59e837..4019b34 100644
--- a/src/config.mak
+++ b/src/config.mak
@@ -2,6 +2,9 @@ PROJNAME = iup
 LIBNAME := iup
 OPT = YES
 
+ifeq "$(TEC_SYSNAME)" "Haiku"
+  USE_HAIKU = Yes
+else
 ifdef GTK_DEFAULT
   ifdef USE_MOTIF
     # Build Motif version in Linux and BSD
@@ -24,6 +27,7 @@ else
     endif
   endif
 endif
+endif
 
 ifdef DBG
   DEFINES += IUP_ASSERT
@@ -44,6 +48,22 @@ SRC = iup_array.c iup_callback.c iup_dlglist.c iup_attrib.c iup_focus.c iup_font
       iup_mask.c iup_maskparse.c iup_tabs.c iup_spin.c iup_list.c iup_getparam.c iup_link.c \
       iup_sbox.c iup_scrollbox.c iup_normalizer.c iup_tree.c iup_split.c iup_layoutdlg.c iup_recplay.c
 
+ifdef USE_HAIKU
+  # Since Haiku has no GTK and no Motif, we can only use the native implementation
+  SRC += haiku/iuphaiku_button.cpp haiku/iuphaiku_canvas.cpp haiku/iuphaiku_clipboard.c \
+         haiku/iuphaiku_colordlg.c haiku/iuphaiku_common.cpp haiku/iuphaiku_dialog.cpp \
+         haiku/iuphaiku_dragdrop.c haiku/iuphaiku_draw.c haiku/iuphaiku_filedlg.cpp \
+         haiku/iuphaiku_focus.cpp haiku/iuphaiku_font.cpp haiku/iuphaiku_fontdlg.c \
+         haiku/iuphaiku_frame.cpp haiku/iuphaiku_globalattrib.c haiku/iuphaiku_help.c \
+         haiku/iuphaiku_image.cpp haiku/iuphaiku_info.cpp haiku/iuphaiku_label.cpp \
+         haiku/iuphaiku_list.cpp haiku/iuphaiku_loop.cpp haiku/iuphaiku_menu.cpp \
+         haiku/iuphaiku_messagedlg.c haiku/iuphaiku_open.cpp haiku/iuphaiku_progressbar.cpp \
+         haiku/iuphaiku_tabs.cpp haiku/iuphaiku_text.cpp haiku/iuphaiku_timer.cpp \
+         haiku/iuphaiku_tips.c haiku/iuphaiku_toggle.cpp haiku/iuphaiku_tree.cpp \
+         haiku/iuphaiku_val.cpp
+  INCLUDES += haiku
+#  DEFINES += _WIN32_WINNT=$(WIN32VER) _WIN32_IE=$(WIN32VER) WINVER=$(WIN32VER) NOTREEVIEW
+else
 ifdef USE_GTK
   CHECK_GTK = Yes
   DEFINES += GTK_DISABLE_DEPRECATED 
@@ -118,6 +138,7 @@ else
   DEFINES += _WIN32_WINNT=$(WIN32VER) _WIN32_IE=0x600 WINVER=$(WIN32VER) NOTREEVIEW
 endif
 endif
+endif
 
 ifneq ($(findstring dll, $(TEC_UNAME)), )
   DEFINES += IUP_DLL
diff --git a/src/haiku/iupgtk_draw_cairo.c b/src/haiku/iupgtk_draw_cairo.c
new file mode 100644
index 0000000..d4a8b14
--- /dev/null
+++ b/src/haiku/iupgtk_draw_cairo.c
@@ -0,0 +1,322 @@
+/** \file
+ * \brief Draw Functions
+ *
+ * See Copyright Notice in "iup.h"
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <memory.h>
+
+#include <gtk/gtk.h>
+
+#include "iup.h"
+
+#include "iup_attrib.h"
+#include "iup_class.h"
+#include "iup_str.h"
+#include "iup_object.h"
+#include "iup_image.h"
+#include "iup_draw.h"
+
+#include "iupgtk_drv.h"
+
+/* This was build for GTK3, but works also for GTK2 */
+
+struct _IdrawCanvas{
+  Ihandle* ih;
+  int w, h;
+
+  GdkWindow* window;
+  cairo_t *cr, *image_cr;
+};
+
+IdrawCanvas* iupDrawCreateCanvas(Ihandle* ih)
+{
+  IdrawCanvas* dc = calloc(1, sizeof(IdrawCanvas));
+  cairo_surface_t* surface;
+
+  dc->ih = ih;
+  dc->window = iupgtkGetWindow(ih->handle);
+  dc->cr = gdk_cairo_create(dc->window);
+
+#if GTK_CHECK_VERSION(2, 24, 0)
+  dc->w = gdk_window_get_width(dc->window);
+  dc->h = gdk_window_get_height(dc->window);
+#else
+  gdk_drawable_get_size(dc->window, &dc->w, &dc->h);
+#endif
+
+  surface = cairo_surface_create_similar(cairo_get_target(dc->cr), CAIRO_CONTENT_COLOR_ALPHA, dc->w, dc->h);
+  dc->image_cr = cairo_create(surface);
+  cairo_surface_destroy(surface);
+
+  return dc;
+}
+
+void iupDrawKillCanvas(IdrawCanvas* dc)
+{
+  cairo_destroy(dc->image_cr);
+  cairo_destroy(dc->cr);
+
+  free(dc);
+}
+
+void iupDrawUpdateSize(IdrawCanvas* dc)
+{
+  int w, h;
+
+#if GTK_CHECK_VERSION(2, 24, 0)
+  w = gdk_window_get_width(dc->window);
+  h = gdk_window_get_height(dc->window);
+#else
+  gdk_drawable_get_size(dc->window, &w, &h);
+#endif
+
+  if (w != dc->w || h != dc->h)
+  {
+    cairo_surface_t* surface;
+
+    dc->w = w;
+    dc->h = h;
+
+    cairo_destroy(dc->image_cr);
+
+    surface = cairo_surface_create_similar(cairo_get_target(dc->cr), CAIRO_CONTENT_COLOR_ALPHA, dc->w, dc->h);
+    dc->image_cr = cairo_create(surface);
+    cairo_surface_destroy(surface);
+  }
+}
+
+void iupDrawFlush(IdrawCanvas* dc)
+{
+  /* flush the writing in the image */
+  cairo_show_page(dc->image_cr);
+
+  cairo_rectangle(dc->cr, 0, 0, dc->w, dc->h);
+  cairo_clip(dc->cr);
+
+  /* creates a pattern from the image and sets it as source in the canvas. */
+  cairo_set_source_surface(dc->cr, cairo_get_target(dc->image_cr), 0, 0);
+
+//  cairo_pattern_set_extend(cairo_get_source(dc->cr), CAIRO_EXTEND_NONE); 
+  cairo_set_operator(dc->cr, CAIRO_OPERATOR_SOURCE);
+  cairo_paint(dc->cr);  /* paints the current source everywhere within the current clip region. */
+}
+
+void iupDrawGetSize(IdrawCanvas* dc, int *w, int *h)
+{
+  if (w) *w = dc->w;
+  if (h) *h = dc->h;
+}
+
+void iupDrawParentBackground(IdrawCanvas* dc)
+{
+  unsigned char r=0, g=0, b=0;
+  char* color = iupBaseNativeParentGetBgColorAttrib(dc->ih);
+  iupStrToRGB(color, &r, &g, &b);
+  iupDrawRectangle(dc, 0, 0, dc->w-1, dc->h-1, r, g, b, IUP_DRAW_FILL);
+}
+
+void iupDrawRectangle(IdrawCanvas* dc, int x1, int y1, int x2, int y2, unsigned char r, unsigned char g, unsigned char b, int style)
+{
+  cairo_set_source_rgba(dc->image_cr, iupCOLOR8ToDouble(r),
+                                       iupCOLOR8ToDouble(g),
+                                       iupCOLOR8ToDouble(b),
+                                       1.0);
+
+  if (style==IUP_DRAW_FILL)
+  {
+    cairo_rectangle(dc->image_cr, x1, y1, x2-x1+1, y2-y1+1);
+    cairo_fill(dc->image_cr);
+  }
+  else
+  {
+    if (style==IUP_DRAW_STROKE_DASH)
+    {
+      double dashes[2];
+      dashes[0] = 6.0;  dashes[1] = 2.0;
+      cairo_set_dash(dc->image_cr, dashes, 2, 0);
+    }
+    else
+      cairo_set_dash(dc->image_cr, 0, 0, 0);
+
+    cairo_rectangle(dc->image_cr, x1, y1, x2-x1, y2-y1);  /* outlined rectangle is actually of size w+1,h+1 */
+    cairo_stroke(dc->image_cr);
+  }
+}
+
+void iupDrawLine(IdrawCanvas* dc, int x1, int y1, int x2, int y2, unsigned char r, unsigned char g, unsigned char b, int style)
+{
+  cairo_set_source_rgba(dc->image_cr, iupCOLOR8ToDouble(r),
+                                       iupCOLOR8ToDouble(g),
+                                       iupCOLOR8ToDouble(b),
+                                       1.0);
+
+  if (style==IUP_DRAW_STROKE_DASH)
+  {
+    double dashes[2];
+    dashes[0] = 6.0;  dashes[1] = 2.0;
+    cairo_set_dash(dc->image_cr, dashes, 2, 0);
+  }
+  else
+    cairo_set_dash(dc->image_cr, 0, 0, 0);
+
+  cairo_move_to(dc->image_cr, x1, y1);
+  cairo_line_to(dc->image_cr, x2, y2);
+  cairo_stroke(dc->image_cr);
+}
+
+void iupDrawArc(IdrawCanvas* dc, int x1, int y1, int x2, int y2, double a1, double a2, unsigned char r, unsigned char g, unsigned char b, int style)
+{
+  int xc, yc, w, h;
+
+  cairo_set_source_rgba(dc->image_cr, iupCOLOR8ToDouble(r),
+                                       iupCOLOR8ToDouble(g),
+                                       iupCOLOR8ToDouble(b),
+                                       1.0);
+
+  if (style!=IUP_DRAW_FILL)
+  {
+    if (style==IUP_DRAW_STROKE_DASH)
+    {
+      double dashes[2];
+      dashes[0] = 6.0;  dashes[1] = 2.0;
+      cairo_set_dash(dc->image_cr, dashes, 2, 0);
+    }
+    else
+      cairo_set_dash(dc->image_cr, 0, 0, 0);
+  }
+
+  w = x2-x1+1;
+  h = y2-y1+1;
+  xc = x1 + w/2;
+  yc = y1 + h/2;
+
+  if (w == h)
+  {
+    cairo_arc(dc->image_cr, xc, yc, 0.5*w, a1, a2);
+
+    if (style==IUP_DRAW_FILL)
+      cairo_fill(dc->image_cr);
+    else
+      cairo_stroke(dc->image_cr);
+  }
+  else  /* Ellipse: change the scale to create from the circle */
+  {
+    cairo_save(dc->image_cr);  /* save to use the local transform */
+
+    cairo_translate(dc->image_cr, xc, yc);
+    cairo_scale(dc->image_cr, w/h, 1.0);
+    cairo_translate(dc->image_cr, -xc, -yc);
+
+    cairo_arc(dc->image_cr, xc, yc, 0.5*h, a1, a2);
+
+    if (style==IUP_DRAW_FILL)
+      cairo_fill(dc->image_cr);
+    else
+      cairo_stroke(dc->image_cr);
+
+    cairo_restore(dc->image_cr);  /* restore from local */
+  }
+}
+
+void iupDrawPolygon(IdrawCanvas* dc, int* points, int count, unsigned char r, unsigned char g, unsigned char b, int style)
+{
+  int i;
+
+  cairo_set_source_rgba(dc->image_cr, iupCOLOR8ToDouble(r),
+                                       iupCOLOR8ToDouble(g),
+                                       iupCOLOR8ToDouble(b),
+                                       1.0);
+
+  if (style!=IUP_DRAW_FILL)
+  {
+    if (style==IUP_DRAW_STROKE_DASH)
+    {
+      double dashes[2];
+      dashes[0] = 6.0;  dashes[1] = 2.0;
+      cairo_set_dash(dc->image_cr, dashes, 2, 0);
+    }
+    else
+      cairo_set_dash(dc->image_cr, 0, 0, 0);
+  }
+
+  cairo_move_to(dc->image_cr, points[0], points[1]);
+  for (i=0; i<count; i++)
+    cairo_line_to(dc->image_cr, points[2*i], points[2*i+1]);
+
+  if (style==IUP_DRAW_FILL)
+    cairo_fill(dc->image_cr);
+  else
+    cairo_stroke(dc->image_cr);
+}
+
+void iupDrawSetClipRect(IdrawCanvas* dc, int x1, int y1, int x2, int y2)
+{
+  cairo_rectangle(dc->image_cr, x1, y1, x2-x1+1, y2-y1+1);
+  cairo_clip(dc->image_cr);
+}
+
+void iupDrawResetClip(IdrawCanvas* dc)
+{
+  cairo_reset_clip(dc->image_cr);
+}
+
+void iupDrawText(IdrawCanvas* dc, const char* text, int len, int x, int y, unsigned char r, unsigned char g, unsigned char b, const char* font)
+{
+  PangoLayout* fontlayout = (PangoLayout*)iupgtkGetPangoLayout(font);
+
+  pango_layout_set_text(fontlayout, iupgtkStrConvertToUTF8(text), len);
+
+  cairo_set_source_rgba(dc->image_cr, iupCOLOR8ToDouble(r),
+                                       iupCOLOR8ToDouble(g),
+                                       iupCOLOR8ToDouble(b),
+                                       1.0);
+
+  pango_cairo_update_layout(dc->image_cr, fontlayout);
+
+  cairo_move_to(dc->image_cr, x, y);
+  pango_cairo_show_layout(dc->image_cr, fontlayout);
+}
+
+void iupDrawImage(IdrawCanvas* dc, const char* name, int make_inactive, int x, int y, int *img_w, int *img_h)
+{
+  int bpp;
+  GdkPixbuf* pixbuf = iupImageGetImage(name, dc->ih, make_inactive);
+  if (!pixbuf)
+    return;
+
+  /* must use this info, since image can be a driver image loaded from resources */
+  iupdrvImageGetInfo(pixbuf, img_w, img_h, &bpp);
+
+  cairo_save (dc->image_cr);
+
+  cairo_rectangle(dc->image_cr, x, y, *img_w, *img_h);
+  cairo_clip(dc->image_cr);
+
+  gdk_cairo_set_source_pixbuf(dc->image_cr, pixbuf, x, y);
+  cairo_paint(dc->image_cr);  /* paints the current source everywhere within the current clip region. */
+
+  /* must restore clipping */
+  cairo_restore (dc->image_cr);
+}
+
+void iupDrawSelectRect(IdrawCanvas* dc, int x, int y, int w, int h)
+{
+  cairo_set_source_rgba(dc->image_cr, 0, 0, 1, 0.80);
+  cairo_rectangle(dc->image_cr, x, y, w, h);
+  cairo_fill(dc->image_cr);
+}
+
+void iupDrawFocusRect(IdrawCanvas* dc, int x, int y, int w, int h)
+{
+#if GTK_CHECK_VERSION(3, 0, 0)
+  GtkStyleContext* context = gtk_widget_get_style_context(dc->ih->handle);
+  gtk_render_focus(context, dc->image_cr, x, y, w, h);
+#else
+  GtkStyle *style = gtk_widget_get_style(dc->ih->handle);
+  gtk_paint_focus(style, dc->window, GTK_STATE_NORMAL, NULL, NULL, NULL, x, y, w, h);
+#endif
+}
diff --git a/src/haiku/iupgtk_key.c b/src/haiku/iupgtk_key.c
new file mode 100644
index 0000000..a63ab57
--- /dev/null
+++ b/src/haiku/iupgtk_key.c
@@ -0,0 +1,443 @@
+/** \file
+ * \brief GTK Driver keyboard mapping
+ *
+ * See Copyright Notice in "iup.h"
+ */
+
+#include <gtk/gtk.h>
+#include <gdk/gdkkeysyms.h>
+#if GTK_CHECK_VERSION(3, 0, 0)
+#include <gdk/gdkkeysyms-compat.h>
+#endif
+
+#include <stdlib.h>      
+#include <stdio.h>      
+
+#include "iup.h"
+#include "iupcbs.h"
+#include "iupkey.h"
+
+#include "iup_object.h"
+#include "iup_key.h"
+
+#include "iup_drv.h"
+#include "iupgtk_drv.h"
+
+
+typedef struct _Igtk2iupkey
+{
+  guint gtkcode;
+  int iupcode;
+  int s_iupcode;
+  int c_iupcode;
+  int m_iupcode;
+  int y_iupcode;
+} Igtk2iupkey;
+
+static Igtk2iupkey gtkkey_map[] = {
+
+{ GDK_Escape,    K_ESC,   K_sESC,    K_cESC,   K_mESC   ,K_yESC   },
+{ GDK_Pause,     K_PAUSE, K_sPAUSE,  K_cPAUSE, K_mPAUSE ,K_yPAUSE },
+{ GDK_Print,     K_Print, K_sPrint,  K_cPrint, K_mPrint ,K_yPrint },
+{ GDK_Menu,      K_Menu,  K_sMenu,   K_cMenu,  K_mMenu  ,K_yMenu  },
+                                                       
+{ GDK_Home,      K_HOME,  K_sHOME,   K_cHOME,  K_mHOME  ,K_yHOME  },
+{ GDK_Up,        K_UP,    K_sUP,     K_cUP,    K_mUP    ,K_yUP    },
+{ GDK_Prior,     K_PGUP,  K_sPGUP,   K_cPGUP,  K_mPGUP  ,K_yPGUP  },
+{ GDK_Left,      K_LEFT,  K_sLEFT,   K_cLEFT,  K_mLEFT  ,K_yLEFT  },
+{ GDK_Begin,     K_MIDDLE,K_sMIDDLE, K_cMIDDLE,K_mMIDDLE,K_yMIDDLE},
+{ GDK_Right,     K_RIGHT, K_sRIGHT,  K_cRIGHT, K_mRIGHT ,K_yRIGHT },
+{ GDK_End,       K_END,   K_sEND,    K_cEND,   K_mEND   ,K_yEND   },
+{ GDK_Down,      K_DOWN,  K_sDOWN,   K_cDOWN,  K_mDOWN  ,K_yDOWN  },
+{ GDK_Next,      K_PGDN,  K_sPGDN,   K_cPGDN,  K_mPGDN  ,K_yPGDN  },
+{ GDK_Insert,    K_INS,   K_sINS,    K_cINS,   K_mINS   ,K_yINS   },
+{ GDK_Delete,    K_DEL,   K_sDEL,    K_cDEL,   K_mDEL   ,K_yDEL   },
+{ GDK_space,     K_SP,    K_sSP,     K_cSP,    K_mSP    ,K_ySP    },
+{ GDK_Tab,       K_TAB,   K_sTAB,    K_cTAB,   K_mTAB   ,K_yTAB   },
+{ GDK_Return,    K_CR,    K_sCR,     K_cCR,    K_mCR    ,K_yCR    },
+{ GDK_BackSpace, K_BS,    K_sBS,     K_cBS,    K_mBS    ,K_yBS    },
+
+{ GDK_1,   K_1, K_exclam,      K_c1, K_m1, K_y1 },
+{ GDK_2,   K_2, K_at,          K_c2, K_m2, K_y2 },
+{ GDK_3,   K_3, K_numbersign,  K_c3, K_m3, K_y3 },
+{ GDK_4,   K_4, K_dollar,      K_c4, K_m4, K_y4 },
+{ GDK_5,   K_5, K_percent,     K_c5, K_m5, K_y5 },
+{ GDK_6,   K_6, K_circum,      K_c6, K_m6, K_y6 },
+{ GDK_7,   K_7, K_ampersand,   K_c7, K_m7, K_y7 },
+{ GDK_8,   K_8, K_asterisk,    K_c8, K_m8, K_y8 },
+{ GDK_9,   K_9, K_parentleft,  K_c9, K_m9, K_y9 },
+{ GDK_0,   K_0, K_parentright, K_c0, K_m0, K_y0 },
+
+/* Shift will be flaged so s_iupcode will contain the right code */
+{ GDK_exclam,     K_1, K_exclam,      K_c1, K_m1, K_y1 },
+{ GDK_at,         K_2, K_at,          K_c2, K_m2, K_y2 },
+{ GDK_numbersign, K_3, K_numbersign,  K_c3, K_m3, K_y3 },
+{ GDK_dollar,     K_4, K_dollar,      K_c4, K_m4, K_y4 },
+{ GDK_percent,    K_5, K_percent,     K_c5, K_m5, K_y5 },
+{ GDK_dead_diaeresis, K_6, K_circum,  K_c6, K_m6, K_y6 },
+{ GDK_ampersand,  K_7, K_ampersand,   K_c7, K_m7, K_y7 },
+{ GDK_asterisk,   K_8, K_asterisk,    K_c8, K_m8, K_y8 },
+{ GDK_parenleft,  K_9, K_parentleft,  K_c9, K_m9, K_y9 },
+{ GDK_parenright, K_0, K_parentright, K_c0, K_m0, K_y0 },
+
+{ GDK_a,   K_a, K_A, K_cA, K_mA, K_yA },
+{ GDK_b,   K_b, K_B, K_cB, K_mB, K_yB },
+{ GDK_c,   K_c, K_C, K_cC, K_mC, K_yC },
+{ GDK_d,   K_d, K_D, K_cD, K_mD, K_yD },
+{ GDK_e,   K_e, K_E, K_cE, K_mE, K_yE },
+{ GDK_f,   K_f, K_F, K_cF, K_mF, K_yF },
+{ GDK_g,   K_g, K_G, K_cG, K_mG, K_yG },
+{ GDK_h,   K_h, K_H, K_cH, K_mH, K_yH },
+{ GDK_i,   K_i, K_I, K_cI, K_mI, K_yI },
+{ GDK_j,   K_j, K_J, K_cJ, K_mJ, K_yJ },
+{ GDK_k,   K_k, K_K, K_cK, K_mK, K_yK },
+{ GDK_l,   K_l, K_L, K_cL, K_mL, K_yL },
+{ GDK_m,   K_m, K_M, K_cM, K_mM, K_yM },
+{ GDK_n,   K_n, K_N, K_cN, K_mN, K_yN },
+{ GDK_o,   K_o, K_O, K_cO, K_mO, K_yO },
+{ GDK_p,   K_p, K_P, K_cP, K_mP, K_yP },
+{ GDK_q,   K_q, K_Q, K_cQ, K_mQ, K_yQ },
+{ GDK_r,   K_r, K_R, K_cR, K_mR, K_yR },
+{ GDK_s,   K_s, K_S, K_cS, K_mS, K_yS },
+{ GDK_t,   K_t, K_T, K_cT, K_mT, K_yT },
+{ GDK_u,   K_u, K_U, K_cU, K_mU, K_yU },
+{ GDK_v,   K_v, K_V, K_cV, K_mV, K_yV },
+{ GDK_w,   K_w, K_W, K_cW, K_mW, K_yW },
+{ GDK_x,   K_x, K_X, K_cX, K_mX, K_yX },
+{ GDK_y,   K_y, K_Y, K_cY, K_mY, K_yY },
+{ GDK_z,   K_z, K_Z, K_cZ, K_mZ, K_yZ },
+
+/* Shift will be flaged so s_iupcode will contain the right code */
+{ GDK_A,   K_a, K_A, K_cA, K_mA, K_yA },
+{ GDK_B,   K_b, K_B, K_cB, K_mB, K_yB },
+{ GDK_C,   K_c, K_C, K_cC, K_mC, K_yC },
+{ GDK_D,   K_d, K_D, K_cD, K_mD, K_yD },
+{ GDK_E,   K_e, K_E, K_cE, K_mE, K_yE },
+{ GDK_F,   K_f, K_F, K_cF, K_mF, K_yF },
+{ GDK_G,   K_g, K_G, K_cG, K_mG, K_yG },
+{ GDK_H,   K_h, K_H, K_cH, K_mH, K_yH },
+{ GDK_I,   K_i, K_I, K_cI, K_mI, K_yI },
+{ GDK_J,   K_j, K_J, K_cJ, K_mJ, K_yJ },
+{ GDK_K,   K_k, K_K, K_cK, K_mK, K_yK },
+{ GDK_L,   K_l, K_L, K_cL, K_mL, K_yL },
+{ GDK_M,   K_m, K_M, K_cM, K_mM, K_yM },
+{ GDK_N,   K_n, K_N, K_cN, K_mN, K_yN },
+{ GDK_O,   K_o, K_O, K_cO, K_mO, K_yO },
+{ GDK_P,   K_p, K_P, K_cP, K_mP, K_yP },
+{ GDK_Q,   K_q, K_Q, K_cQ, K_mQ, K_yQ },
+{ GDK_R,   K_r, K_R, K_cR, K_mR, K_yR },
+{ GDK_S,   K_s, K_S, K_cS, K_mS, K_yS },
+{ GDK_T,   K_t, K_T, K_cT, K_mT, K_yT },
+{ GDK_U,   K_u, K_U, K_cU, K_mU, K_yU },
+{ GDK_V,   K_v, K_V, K_cV, K_mV, K_yV },
+{ GDK_W,   K_w, K_W, K_cW, K_mW, K_yW },
+{ GDK_X,   K_x, K_X, K_cX, K_mX, K_yX },
+{ GDK_Y,   K_y, K_Y, K_cY, K_mY, K_yY },
+{ GDK_Z,   K_z, K_Z, K_cZ, K_mZ, K_yZ },
+
+{ GDK_F1,  K_F1,  K_sF1,  K_cF1,  K_mF1,  K_yF1 },
+{ GDK_F2,  K_F2,  K_sF2,  K_cF2,  K_mF2,  K_yF2 },
+{ GDK_F3,  K_F3,  K_sF3,  K_cF3,  K_mF3,  K_yF3 },
+{ GDK_F4,  K_F4,  K_sF4,  K_cF4,  K_mF4,  K_yF4 },
+{ GDK_F5,  K_F5,  K_sF5,  K_cF5,  K_mF5,  K_yF5 },
+{ GDK_F6,  K_F6,  K_sF6,  K_cF6,  K_mF6,  K_yF6 },
+{ GDK_F7,  K_F7,  K_sF7,  K_cF7,  K_mF7,  K_yF7 },
+{ GDK_F8,  K_F8,  K_sF8,  K_cF8,  K_mF8,  K_yF8 },
+{ GDK_F9,  K_F9,  K_sF9,  K_cF9,  K_mF9,  K_yF9 },
+{ GDK_F10, K_F10, K_sF10, K_cF10, K_mF10, K_yF10 },
+{ GDK_F11, K_F11, K_sF11, K_cF11, K_mF11, K_yF11 },
+{ GDK_F12, K_F12, K_sF12, K_cF12, K_mF12, K_yF12 },
+
+{ GDK_semicolon,   K_semicolon,    K_colon,      K_cSemicolon, K_mSemicolon, K_ySemicolon },
+{ GDK_equal,       K_equal,        K_plus,       K_cEqual,     K_mEqual,  K_yEqual },
+{ GDK_comma,       K_comma,        K_less,       K_cComma,     K_mComma,  K_yComma },
+{ GDK_minus,       K_minus,        K_underscore, K_cMinus,     K_mMinus,  K_yMinus },
+{ GDK_period,      K_period,       K_greater,    K_cPeriod,    K_mPeriod, K_yPeriod },
+{ GDK_slash,       K_slash,        K_question,   K_cSlash,     K_mSlash,  K_ySlash },
+{ GDK_grave,       K_grave,        K_tilde,      0, 0, 0 },
+{ GDK_bracketleft, K_bracketleft,  K_braceleft,  K_cBracketleft, K_mBracketleft, K_yBracketleft },
+{ GDK_backslash,   K_backslash,    K_bar,        K_cBackslash,   K_mBackslash,   K_yBackslash },
+{ GDK_bracketright,K_bracketright, K_braceright, K_cBracketright,K_mBracketright,K_yBracketright },
+{ GDK_apostrophe,  K_apostrophe,   K_quotedbl,   0, 0, 0 },
+
+/* Shift will be flaged so s_iupcode will contain the right code */
+{ GDK_colon,      K_semicolon,    K_colon,      K_cSemicolon, K_mSemicolon, K_ySemicolon },
+{ GDK_plus,       K_equal,        K_plus,       K_cEqual,     K_mEqual,  K_yEqual },
+{ GDK_less,       K_comma,        K_less,       K_cComma,     K_mComma,  K_yComma },
+{ GDK_underscore, K_minus,        K_underscore, K_cMinus,     K_mMinus,  K_yMinus },
+{ GDK_greater,    K_period,       K_greater,    K_cPeriod,    K_mPeriod, K_yPeriod },
+{ GDK_question,   K_slash,        K_question,   K_cSlash,     K_mSlash,  K_ySlash },
+{ GDK_braceleft,  K_bracketleft,  K_braceleft,  K_cBracketleft, K_mBracketleft, K_yBracketleft },
+{ GDK_bar,        K_backslash,    K_bar,        K_cBackslash,   K_mBackslash,   K_yBackslash },
+{ GDK_braceright, K_bracketright, K_braceright, K_cBracketright,K_mBracketright,K_yBracketright },
+{ GDK_quotedbl,   K_apostrophe,   K_quotedbl,   0, 0, 0 },
+
+{ GDK_KP_0,   K_0, K_0,  K_c0, K_m0, K_y0 },
+{ GDK_KP_1,   K_1, K_1,  K_c1, K_m1, K_y1 },
+{ GDK_KP_2,   K_2, K_2,  K_c2, K_m2, K_y2 },
+{ GDK_KP_3,   K_3, K_3,  K_c3, K_m3, K_y3 },
+{ GDK_KP_4,   K_4, K_4,  K_c4, K_m4, K_y4 },
+{ GDK_KP_5,   K_5, K_5,  K_c5, K_m5, K_y5 },
+{ GDK_KP_6,   K_6, K_6,  K_c6, K_m6, K_y6 },
+{ GDK_KP_7,   K_7, K_7,  K_c7, K_m7, K_y7 },
+{ GDK_KP_8,   K_8, K_8,  K_c8, K_m8, K_y8 },
+{ GDK_KP_9,   K_9, K_9,  K_c9, K_m9, K_y9 },
+{ GDK_KP_Multiply,  K_asterisk, K_sAsterisk, K_cAsterisk, K_mAsterisk, K_yAsterisk },
+{ GDK_KP_Add,       K_plus,     K_sPlus,     K_cPlus,     K_mPlus,     K_yPlus },
+{ GDK_KP_Subtract,  K_minus,    K_sMinus,    K_cMinus,    K_mMinus,    K_yMinus },
+{ GDK_KP_Decimal,   K_period,   K_sPeriod,   K_cPeriod,   K_mPeriod,   K_yPeriod },
+{ GDK_KP_Divide,    K_slash,    K_sSlash,    K_cSlash,    K_mSlash,    K_ySlash },
+{ GDK_KP_Separator, K_comma,    K_sComma,    K_cComma,    K_mComma,    K_yComma },
+
+{ GDK_ccedilla,     K_ccedilla, K_Ccedilla, K_cCcedilla, K_mCcedilla, K_yCcedilla },
+{ GDK_Ccedilla,     K_ccedilla, K_Ccedilla, K_cCcedilla, K_mCcedilla, K_yCcedilla },
+
+{ GDK_dead_tilde,      K_tilde, K_circum, 0, 0, 0 },
+{ GDK_dead_acute,      K_acute, K_grave,  0, 0, 0 },
+{ GDK_dead_grave,      K_grave, K_tilde,  0, 0, 0 },
+{ GDK_dead_circumflex, K_tilde, K_circum, 0, 0, 0 },
+
+{ GDK_KP_F1,        K_F1,    K_sF1,    K_cF1,    K_mF1,    K_yF1 },
+{ GDK_KP_F2,        K_F2,    K_sF2,    K_cF2,    K_mF2,    K_yF2 },
+{ GDK_KP_F3,        K_F3,    K_sF3,    K_cF3,    K_mF3,    K_yF3 },
+{ GDK_KP_F4,        K_F4,    K_sF4,    K_cF4,    K_mF4,    K_yF4 },
+{ GDK_KP_Space,     K_SP,    K_sSP,    K_cSP,    K_mSP    ,K_ySP    },
+{ GDK_KP_Tab,       K_TAB,   K_sTAB,   K_cTAB,   K_mTAB   ,K_yTAB   },
+{ GDK_KP_Equal,     K_equal, 0,        K_cEqual, K_mEqual, K_yEqual },
+
+{ GDK_KP_Enter,     K_CR,    K_sCR,     K_cCR,    K_mCR,    K_yCR    },
+{ GDK_KP_Home,      K_HOME,  K_sHOME,   K_cHOME,  K_mHOME,  K_yHOME  },
+{ GDK_KP_Up,        K_UP,    K_sUP,     K_cUP,    K_mUP,    K_yUP    },
+{ GDK_KP_Page_Up,   K_PGUP,  K_sPGUP,   K_cPGUP,  K_mPGUP,  K_yPGUP  },
+{ GDK_KP_Left,      K_LEFT,  K_sLEFT,   K_cLEFT,  K_mLEFT,  K_yLEFT  },
+{ GDK_KP_Begin,     K_MIDDLE,K_sMIDDLE, K_cMIDDLE,K_mMIDDLE,K_yMIDDLE},
+{ GDK_KP_Right,     K_RIGHT, K_sRIGHT,  K_cRIGHT, K_mRIGHT, K_yRIGHT },
+{ GDK_KP_End,       K_END,   K_sEND,    K_cEND,   K_mEND,   K_yEND   },
+{ GDK_KP_Down,      K_DOWN,  K_sDOWN,   K_cDOWN,  K_mDOWN,  K_yDOWN  },
+{ GDK_KP_Page_Down, K_PGDN,  K_sPGDN,   K_cPGDN,  K_mPGDN,  K_yPGDN  },
+{ GDK_KP_Insert,    K_INS,   K_sINS,    K_cINS,   K_mINS,   K_yINS   },
+{ GDK_KP_Delete,    K_DEL,   K_sDEL,    K_cDEL,   K_mDEL,   K_yDEL   }
+
+};
+
+void iupdrvKeyEncode(int key, unsigned int *keyval, unsigned int *state)
+{
+  int i, iupcode = key & 0xFF; /* 0-255 interval */
+  int count = sizeof(gtkkey_map)/sizeof(gtkkey_map[0]);
+  for (i = 0; i < count; i++)
+  {
+    Igtk2iupkey* key_map = &(gtkkey_map[i]);
+    if (key_map->iupcode == iupcode)
+    {
+      *keyval = key_map->gtkcode;
+      *state = 0;
+
+      if (iupcode != key)
+      {
+        if (key_map->c_iupcode == key)
+          *state = GDK_CONTROL_MASK;
+        else if (key_map->m_iupcode == key)
+          *state = GDK_MOD1_MASK;
+        else if (key_map->y_iupcode == key)
+          *state = GDK_MOD4_MASK;
+        else if (key_map->s_iupcode == key)
+          *state = GDK_SHIFT_MASK;
+      }
+      return;
+    }
+    else if (key_map->s_iupcode == key)   /* There are Shift keys below 256 */
+    {
+      *keyval = key_map->gtkcode;
+      *state = GDK_SHIFT_MASK;
+
+      if ((*keyval >= GDK_a) &&
+          (*keyval <= GDK_z))
+      {
+        /* remap to upper case */
+        *keyval -= GDK_a-GDK_A;
+      }
+      return;
+    }
+  }
+}
+
+static int gtkKeyMap2Iup(int state, int i)
+{
+  int code = 0;
+  if (state & GDK_CONTROL_MASK)   /* Ctrl */
+    code = gtkkey_map[i].c_iupcode;
+  else if (state & GDK_MOD1_MASK ||
+           state & GDK_MOD5_MASK) /* Alt */
+    code = gtkkey_map[i].m_iupcode;
+  else if (state & GDK_MOD4_MASK) /* Apple/Win */
+    code = gtkkey_map[i].y_iupcode;
+  else if (state & GDK_LOCK_MASK) /* CapsLock */
+  {
+    if ((state & GDK_SHIFT_MASK) || !iupKeyCanCaps(gtkkey_map[i].iupcode))
+      return gtkkey_map[i].iupcode;
+    else
+      code = gtkkey_map[i].s_iupcode;
+  }
+  else if (state & GDK_SHIFT_MASK) /* Shift */
+    code = gtkkey_map[i].s_iupcode;
+  else
+    return gtkkey_map[i].iupcode;
+
+  if (!code)
+    code = gtkkey_map[i].iupcode;
+
+  return code;
+}
+
+int iupgtkKeyDecode(GdkEventKey *evt)
+{
+  int i;
+  int count = sizeof(gtkkey_map)/sizeof(gtkkey_map[0]);
+  guint keyval = evt->keyval;
+
+  if ((evt->state & GDK_MOD2_MASK) && /* NumLock */
+      (keyval >= GDK_KP_Home) &&
+      (keyval <= GDK_KP_Delete))
+  {
+    /* remap to numeric keys */
+    guint remap_numkey[] = {GDK_KP_7, GDK_KP_4, GDK_KP_8, GDK_KP_6, GDK_KP_2, GDK_KP_9, GDK_KP_3, GDK_KP_1, GDK_KP_5, GDK_KP_0, GDK_KP_Decimal};
+    keyval = remap_numkey[keyval-GDK_KP_Home];
+  }
+
+  for (i = 0; i < count; i++)
+  {
+    if (gtkkey_map[i].gtkcode == keyval)
+      return gtkKeyMap2Iup(evt->state, i);
+  }
+
+  return 0;
+}
+
+static int iupObjectIsNativeContainer(Ihandle* ih)
+{
+  if (ih->iclass->childtype != IUP_CHILDNONE && 
+      ih->iclass->nativetype != IUP_TYPEVOID)
+    return 1;
+  else
+    return 0;
+}
+
+gboolean iupgtkKeyPressEvent(GtkWidget *widget, GdkEventKey *evt, Ihandle *ih)
+{
+  int result;
+  int code = iupgtkKeyDecode(evt);
+  if (code == 0) 
+    return FALSE;
+
+  /* Avoid duplicate calls if a child of a native container contains the focus.
+     GTK will call the callback for the child and for the container.
+     Ignore the one sent to the parent. For now only IupDialog and IupTabs
+     have keyboard signals intercepted.
+     */
+  if (iupObjectIsNativeContainer(ih))
+  {
+    GtkWindow* win = (GtkWindow*)IupGetDialog(ih)->handle;
+    GtkWidget *widget_focus = gtk_window_get_focus(win);
+    if (widget_focus && widget_focus != widget)
+      return FALSE;
+  }
+
+  result = iupKeyCallKeyCb(ih, code);
+  if (result == IUP_CLOSE)
+  {
+    IupExitLoop();
+    return FALSE;
+  }
+  if (result == IUP_IGNORE)
+    return TRUE;
+
+  /* in the previous callback the dialog could be destroyed */
+  if (iupObjectCheck(ih))
+  {
+    /* this is called only for canvas */
+    if (ih->iclass->nativetype == IUP_TYPECANVAS) 
+    {
+      result = iupKeyCallKeyPressCb(ih, code, 1);
+      if (result == IUP_CLOSE)
+      {
+        IupExitLoop();
+        return FALSE;
+      }
+      if (result == IUP_IGNORE)
+        return TRUE;
+    }
+
+    if (!iupKeyProcessNavigation(ih, code, evt->state & GDK_SHIFT_MASK))
+      return TRUE;
+
+    /* compensate the show-help limitation. 
+     * It is not called on F1, only on Shift+F1 and Ctrl+F1. */
+    if (code == K_F1)
+    {
+      Icallback cb = IupGetCallback(ih, "HELP_CB");
+      if (cb)
+      {
+        if (cb(ih) == IUP_CLOSE) 
+          IupExitLoop();
+      }
+    }
+  }
+
+  (void)widget;
+  return FALSE;
+}
+
+gboolean iupgtkKeyReleaseEvent(GtkWidget *widget, GdkEventKey *evt, Ihandle *ih)
+{
+  /* this is called only for canvas */
+  int result;
+  int code = iupgtkKeyDecode(evt);
+  if (code == 0) 
+    return FALSE;
+
+  result = iupKeyCallKeyPressCb(ih, code, 0);
+  if (result == IUP_CLOSE)
+  {
+    IupExitLoop();
+    return FALSE;
+  }
+  if (result == IUP_IGNORE)
+    return TRUE;
+
+  (void)widget;
+  return FALSE;
+}
+
+void iupgtkButtonKeySetStatus(guint state, unsigned int but, char* status, int doubleclick)
+{
+  if (state & GDK_SHIFT_MASK)
+    iupKEY_SETSHIFT(status);
+
+  if (state & GDK_CONTROL_MASK)
+    iupKEY_SETCONTROL(status); 
+
+  if ((state & GDK_BUTTON1_MASK) || but==1)
+    iupKEY_SETBUTTON1(status);
+
+  if ((state & GDK_BUTTON2_MASK) || but==2)
+    iupKEY_SETBUTTON2(status);
+
+  if ((state & GDK_BUTTON3_MASK) || but==3)
+    iupKEY_SETBUTTON3(status);
+
+  if ((state & GDK_BUTTON4_MASK) || but==4)
+    iupKEY_SETBUTTON4(status);
+
+  if ((state & GDK_BUTTON5_MASK) || but==5)
+    iupKEY_SETBUTTON5(status);
+
+  if (state & GDK_MOD1_MASK || state & GDK_MOD5_MASK) /* Alt */
+    iupKEY_SETALT(status);
+
+  if (state & GDK_MOD4_MASK) /* Apple/Win */
+    iupKEY_SETSYS(status);
+
+  if (doubleclick)
+    iupKEY_SETDOUBLE(status);
+}
+
diff --git a/src/haiku/iuphaiku_button.cpp b/src/haiku/iuphaiku_button.cpp
new file mode 100644
index 0000000..aced623
--- /dev/null
+++ b/src/haiku/iuphaiku_button.cpp
@@ -0,0 +1,286 @@
+/** \file
+ * \brief Button Control
+ *
+ * See Copyright Notice in "iup.h"
+ */
+
+#define UNIMPLEMENTED printf("%s (%s %d) UNIMPLEMENTED\n",__func__,__FILE__,__LINE__);
+
+#include <Button.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <memory.h>
+#include <stdarg.h>
+
+#include "iup.h"
+#include "iupcbs.h"
+
+#include "iup_object.h"
+#include "iup_layout.h"
+#include "iup_attrib.h"
+#include "iup_str.h"
+#include "iup_image.h"
+#include "iup_button.h"
+#include "iup_drv.h"
+#include "iup_drvfont.h"
+#include "iup_image.h"
+#include "iup_key.h"
+
+#include "iuphaiku_drv.h"
+
+class IUPButton: public BButton
+{
+  public:
+	IUPButton(BMessage* msg)
+	  : BButton(BRect(0,0,10,10), "button", NULL, msg)
+	  , fBitmap(NULL)
+	{
+	}
+
+	void Draw(BRect updateRect)
+	{
+	  BButton::Draw(updateRect);
+	  if (fBitmap) {
+		MovePenTo(6, 6);
+		SetDrawingMode(B_OP_ALPHA);
+	    DrawBitmapAsync(fBitmap);
+	  }
+	}
+
+	void SetBitmap(BBitmap* bitmap)
+	{
+      fBitmap = bitmap;
+	}
+
+  private:
+	BBitmap* fBitmap;
+};
+
+void iupdrvButtonAddBorders(int *x, int *y)
+{
+  // TODO can we use BControlLook here ?
+  int border_size = 2*7+1; /* borders are not symetric */
+  (*x) += border_size;
+  (*y) += border_size;
+}
+
+static int beButtonSetTitleAttrib(Ihandle* ih, const char* value)
+{
+  BButton* button = (BButton*)ih->handle;
+  button->SetLabel(value);
+  return 1;
+}
+
+static int haikuButtonSetAlignmentAttrib(Ihandle* ih, const char* value)
+{
+  char value1[30]="", value2[30]="";
+  iupStrToStrStr(value, value1, value2, ':');
+  
+  if (iupStrEqualNoCase(value1, "ARIGHT"))
+	UNIMPLEMENTED
+  else if (iupStrEqualNoCase(value1, "ACENTER"))
+  {
+	// This is the default behavior in HAIKU
+	// TODO actually restore it when the others are handled
+  }
+  else /* "ALEFT" */
+	UNIMPLEMENTED
+
+  if (iupStrEqualNoCase(value2, "ABOTTOM"))
+	UNIMPLEMENTED
+  else if (iupStrEqualNoCase(value2, "ATOP"))
+	UNIMPLEMENTED
+  else  /* ACENTER (default) */
+  {
+	// This is the default behavior in HAIKU
+	// TODO actually restore it when the others are handled
+  }
+
+  return 1;
+}
+
+static int haikuButtonSetPaddingAttrib(Ihandle* ih, const char* value)
+{
+  iupStrToIntInt(value, &ih->data->horiz_padding, &ih->data->vert_padding, 'x');
+  if (ih->handle)
+  {
+    if (ih->data->type == IUP_BUTTON_TEXT)   /* text only */
+    {
+	  UNIMPLEMENTED
+    }
+    else
+    {
+	  UNIMPLEMENTED
+    }
+    return 0;
+  }
+  else
+    return 1; /* store until not mapped, when mapped will be set again */
+}
+
+static int gtkButtonSetFgColorAttrib(Ihandle* ih, const char* value)
+{
+	UNIMPLEMENTED
+  return 0;
+}
+
+/*
+static int gtkButtonSetStandardFontAttrib(Ihandle* ih, const char* value)
+{
+	UNIMPLEMENTED
+  return 0;
+}
+*/
+
+/* FIXME this is copypasted from the same method for Toggle. we should share it. */
+static void gtkButtonSetPixbuf(Ihandle* ih, const char* name, int make_inactive)
+{
+  IUPButton* button = (IUPButton*)ih->handle;
+
+  if (name)
+  {
+	BBitmap* bitmap = (BBitmap*)iupImageGetImage(name, ih, make_inactive);
+	button->SetBitmap(bitmap);
+  }
+}
+
+static int gtkButtonSetImageAttrib(Ihandle* ih, const char* value)
+{
+  if (ih->data->type & IUP_BUTTON_IMAGE)
+  {
+    if (iupdrvIsActive(ih))
+      gtkButtonSetPixbuf(ih, value, 0);
+    else
+    {
+      if (!iupAttribGet(ih, "IMINACTIVE"))
+      {
+        /* if not active and IMINACTIVE is not defined 
+           then automaticaly create one based on IMAGE */
+        gtkButtonSetPixbuf(ih, value, 1); /* make_inactive */
+      }
+    }
+    return 1;
+  }
+  else
+    return 0;
+}
+
+static int gtkButtonSetImInactiveAttrib(Ihandle* ih, const char* value)
+{
+  if (ih->data->type & IUP_BUTTON_IMAGE)
+  {
+    if (!iupdrvIsActive(ih))
+    {
+      if (value)
+        gtkButtonSetPixbuf(ih, value, 0);
+      else
+      {
+        /* if not defined then automaticaly create one based on IMAGE */
+        char* name = iupAttribGet(ih, "IMAGE");
+        gtkButtonSetPixbuf(ih, name, 1); /* make_inactive */
+      }
+    }
+    return 1;
+  }
+  else
+    return 0;
+}
+
+static int gtkButtonSetActiveAttrib(Ihandle* ih, const char* value)
+{
+  /* update the inactive image if necessary */
+  if (ih->data->type & IUP_BUTTON_IMAGE)
+  {
+    if (!iupStrBoolean(value))
+    {
+      char* name = iupAttribGet(ih, "IMINACTIVE");
+      if (name)
+        gtkButtonSetPixbuf(ih, name, 0);
+      else
+      {
+        /* if not defined then automaticaly create one based on IMAGE */
+        name = iupAttribGet(ih, "IMAGE");
+        gtkButtonSetPixbuf(ih, name, 1); /* make_inactive */
+      }
+    }
+    else
+    {
+      /* must restore the normal image */
+      char* name = iupAttribGet(ih, "IMAGE");
+      gtkButtonSetPixbuf(ih, name, 0);
+    }
+  }
+
+  return iupBaseSetActiveAttrib(ih, value);
+}
+
+static int gtkButtonMapMethod(Ihandle* ih)
+{
+  char* value;
+  value = iupAttribGet(ih, "IMAGE");
+  char* title = iupAttribGet(ih, "TITLE");
+
+  BMessage* msg = new BMessage(buttonInvoke);
+  msg->AddPointer("iHandle", ih);
+
+  BButton* button = new IUPButton(msg);
+
+  if (value)
+  {
+    ih->data->type = IUP_BUTTON_IMAGE;
+
+    if (title && *title!=0) {
+      ih->data->type |= IUP_BUTTON_TEXT;
+	} 
+  } else {
+    ih->data->type = IUP_BUTTON_TEXT;
+	button->SetLabel(title);
+  }
+
+  ih->handle = (InativeHandle*)button;
+
+  iuphaikuBaseAddToParent(ih);
+  return IUP_NOERROR;
+}
+
+void iupdrvButtonInitClass(Iclass* ic)
+{
+  /* Driver Dependent Class functions */
+  ic->Map = gtkButtonMapMethod;
+
+  /* Driver Dependent Attribute functions */
+
+  /* Overwrite Common */
+//  iupClassRegisterAttribute(ic, "STANDARDFONT", NULL, gtkButtonSetStandardFontAttrib, IUPAF_SAMEASSYSTEM, "DEFAULTFONT", IUPAF_NO_SAVE|IUPAF_NOT_MAPPED);
+
+  /* Overwrite Visual */
+  iupClassRegisterAttribute(ic, "ACTIVE", iupBaseGetActiveAttrib, gtkButtonSetActiveAttrib, IUPAF_SAMEASSYSTEM, "YES", IUPAF_DEFAULT);
+
+  /* Visual */
+  iupClassRegisterAttribute(ic, "BGCOLOR", NULL, iupdrvBaseSetBgColorAttrib, IUPAF_SAMEASSYSTEM, "DLGBGCOLOR", IUPAF_DEFAULT);
+
+  /* Special */
+  iupClassRegisterAttribute(ic, "FGCOLOR", NULL, gtkButtonSetFgColorAttrib, IUPAF_SAMEASSYSTEM, "DLGFGCOLOR", IUPAF_DEFAULT);
+  iupClassRegisterAttribute(ic, "TITLE", NULL, beButtonSetTitleAttrib, NULL, NULL, IUPAF_NO_DEFAULTVALUE|IUPAF_NO_INHERIT);
+
+  /* IupButton only */
+  iupClassRegisterAttribute(ic, "ALIGNMENT", NULL, haikuButtonSetAlignmentAttrib, "ACENTER:ACENTER", NULL, IUPAF_NO_INHERIT);  /* force new default value */
+  iupClassRegisterAttribute(ic, "IMAGE", NULL, gtkButtonSetImageAttrib, NULL, NULL, IUPAF_IHANDLENAME|IUPAF_NO_DEFAULTVALUE|IUPAF_NO_INHERIT);
+  iupClassRegisterAttribute(ic, "IMINACTIVE", NULL, gtkButtonSetImInactiveAttrib, NULL, NULL, IUPAF_IHANDLENAME|IUPAF_NO_DEFAULTVALUE|IUPAF_NO_INHERIT);
+  iupClassRegisterAttribute(ic, "IMPRESS", NULL, NULL, NULL, NULL, IUPAF_IHANDLENAME|IUPAF_NO_DEFAULTVALUE|IUPAF_NO_INHERIT);
+
+  iupClassRegisterAttribute(ic, "PADDING", iupButtonGetPaddingAttrib, haikuButtonSetPaddingAttrib, IUPAF_SAMEASSYSTEM, "0x0", IUPAF_NOT_MAPPED);
+  iupClassRegisterAttribute(ic, "MARKUP", NULL, NULL, NULL, NULL, IUPAF_DEFAULT);
+}
+
+void iuphaikuButtonInvoked(Ihandle* ih)
+{
+  Icallback cb = IupGetCallback(ih, "ACTION");
+  if (cb)
+  {
+    if (cb(ih) == IUP_CLOSE) 
+      IupExitLoop();
+  }
+}
diff --git a/src/haiku/iuphaiku_canvas.cpp b/src/haiku/iuphaiku_canvas.cpp
new file mode 100644
index 0000000..8c83345
--- /dev/null
+++ b/src/haiku/iuphaiku_canvas.cpp
@@ -0,0 +1,277 @@
+/** \file
+ * \brief Canvas Control
+ *
+ * See Copyright Notice in "iup.h"
+ */
+
+#include <ScrollView.h>
+#include <View.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <memory.h>
+#include <stdarg.h>
+#include <limits.h>
+
+#include "iup.h"
+#include "iupcbs.h"
+
+#include "iup_object.h"
+#include "iup_layout.h"
+#include "iup_attrib.h"
+#include "iup_dialog.h"
+#include "iup_str.h"
+#include "iup_drv.h"
+#include "iup_drvinfo.h"
+#include "iup_drvfont.h"
+#include "iup_canvas.h"
+#include "iup_key.h"
+
+#include "iuphaiku_drv.h"
+
+#define UNIMPLEMENTED printf("%s (%s %d) UNIMPLEMENTED\n",__func__,__FILE__,__LINE__);
+
+#define GTK_TYPE_IUPDRAWING_AREA            (iup_gtk_drawing_area_get_type ())
+#define GTK_IUPDRAWING_AREA(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_IUPDRAWING_AREA, GtkIupDrawingArea))
+
+enum {
+   PROP_0,
+   PROP_HADJUSTMENT,
+   PROP_VADJUSTMENT,
+   PROP_HSCROLL_POLICY,
+   PROP_VSCROLL_POLICY
+};
+
+static int gtkCanvasSetBgColorAttrib(Ihandle* ih, const char* value);
+
+static int gtkCanvasSetXAutoHideAttrib(Ihandle* ih, const char *value)
+{
+	UNIMPLEMENTED
+  return 1;
+}
+
+static int gtkCanvasSetYAutoHideAttrib(Ihandle* ih, const char *value)
+{
+	UNIMPLEMENTED
+  return 1;
+}
+
+static int gtkCanvasSetDXAttrib(Ihandle* ih, const char *value)
+{
+	UNIMPLEMENTED
+  return 1;
+}
+
+static int gtkCanvasSetDYAttrib(Ihandle* ih, const char *value)
+{
+	UNIMPLEMENTED
+  return 1;
+}
+
+static BView* iuphaikuGetScrolled(Ihandle* ih)
+{
+  BScrollView* sv = (BScrollView*)ih->handle;
+  BScrollBar* sb = sv->ScrollBar(B_HORIZONTAL);
+  if(!sb) sb = sv->ScrollBar(B_VERTICAL);
+  return sb->Target();
+}
+
+static int gtkCanvasSetPosXAttrib(Ihandle* ih, const char *value)
+{
+  float posx, xmin, xmax, dx;
+  if (!(ih->data->sb & IUP_SB_HORIZ))
+	return 1;
+  if (!iupStrToFloat(value, &posx))
+    return 1;
+
+  xmin = iupAttribGetFloat(ih, "XMIN");
+  xmax = iupAttribGetFloat(ih, "XMAX");
+  dx = iupAttribGetFloat(ih, "DX");
+
+  if (posx < xmin) posx = xmin;
+  if (posx > (xmax - dx)) posx = xmax - dx;
+  ih->data->posx = posx;
+
+  BView* canvas = iuphaikuGetScrolled(ih);
+
+  BPoint curPos = canvas->LeftTop();
+  curPos.x = posx;
+  canvas->ScrollTo(curPos);
+
+  return 1;
+}
+
+static int gtkCanvasSetPosYAttrib(Ihandle* ih, const char *value)
+{
+  float posy, ymin, ymax, dy;
+  if (!iupStrToFloat(value, &posy))
+    return 1;
+  ymin = iupAttribGetFloat(ih, "YMIN");
+  ymax = iupAttribGetFloat(ih, "YMAX");
+  dy = iupAttribGetFloat(ih, "DY");
+
+  if (posy < ymin) posy = ymin;
+  if (posy > (ymax - dy)) posy = ymax - dy;
+  ih->data->posy = posy;
+
+  BView* canvas = (BView*)iupAttribGetStr(ih, "DRAWABLE");
+  BPoint origin = canvas->LeftTop();
+  canvas->ScrollTo(origin.x, posy);
+  
+  return 1;
+}
+
+static int gtkCanvasSetBgColorAttrib(Ihandle* ih, const char* value)
+{
+  // TODO This will set the color for the BScrollView. Is it ok ?
+  return iupdrvBaseSetBgColorAttrib(ih, value);
+	/*
+  BView* canvas = iuphaikuGetScrolled(ih);
+  unsigned char r, g, b;
+  
+  if (iupStrToRGB(parent_value, &r, &g, &b))
+  {
+  }
+  
+  canvas->SetViewColor();
+  canvas->SetLowColor();
+  return 1;
+  */
+}
+
+static void haikuCanvasLayoutUpdateMethod(Ihandle *ih)
+{
+  iupdrvBaseLayoutUpdateMethod(ih);
+
+  // Also resize the child
+  BView* canvas = (BView*)iupAttribGetStr(ih, "DRAWABLE");
+  // TODO we need to substract the scrollbar size, and maybe the canvas wants to
+  // be bigger and have scrollbars...
+  canvas->ResizeTo(ih->currentwidth - 2, ih->currentheight - 2);
+}
+
+static char* gtkCanvasGetDrawSizeAttrib(Ihandle *ih)
+{
+	UNIMPLEMENTED
+		return NULL;
+}
+
+class IUPCanvas: public BView
+{
+  public:
+	IUPCanvas(Ihandle* ih)
+	  : BView(BRect(0, 0, 10, 10), "canvas", B_FOLLOW_ALL_SIDES, B_WILL_DRAW | B_FRAME_EVENTS) 
+	  , fHandle(ih)
+	{}
+
+	void Draw(BRect rect)
+	{
+      iupAttribSetStrf(fHandle, "CLIPRECT", "%d %d %d %d", rect.left, rect.top, rect.right, rect.bottom);
+      IFnff cb = (IFnff)IupGetCallback(fHandle,"ACTION");
+      if (cb) {
+		LockLooper();
+        cb (fHandle, fHandle->data->posx, fHandle->data->posy);
+		UnlockLooper();
+	  }
+	}
+
+	// TODO handle ScrollBy/ScrollTo (manage X/YMIN/MAX, DX,DY, call SCROLL_CB
+	// TODO handle size changes and call iupdrvBaseLayoutUpdateMethod(ih);
+	// TODO handle events (focus, key press/release, enter, leave, ...)
+	void FrameResized(float w, float h)
+	{
+      IFnii cb = (IFnii)IupGetCallback(fHandle, "RESIZE_CB");
+      if (cb) {
+		if (!LockLooper()) debugger("Failed to lock view from FrameResized");
+        cb(fHandle, (int)w, (int)h);
+		UnlockLooper();
+	  }
+	}
+  private:
+	Ihandle* fHandle;
+};
+
+static int haikuCanvasMapMethod(Ihandle* ih)
+{
+  if (!ih->parent)
+    return IUP_ERROR;
+
+  bool scrollh = false;
+  bool scrollv = false;
+  border_style border = B_NO_BORDER; 
+
+  ih->data->sb = iupBaseGetScrollbar(ih);
+  if (ih->data->sb & IUP_SB_HORIZ)
+    scrollh = true;
+  if (ih->data->sb & IUP_SB_VERT)
+	scrollv = true;
+
+  if (iupAttribGetBoolean(ih, "BORDER"))
+  {
+    iupAttribSetInt(ih, "BORDERWIDTH", 1);
+    border = B_FANCY_BORDER;
+  }
+
+  int flags = 0; 
+
+  /* To receive keyboard events, you will need to set the GTK_CAN_FOCUS flag on
+   * the drawing area. */
+  if (ih->iclass->is_interactive)
+  {
+    if (iupAttribGetBoolean(ih, "CANFOCUS"))
+	  flags |= B_NAVIGABLE;
+  }
+
+  BView* canvas = new IUPCanvas(ih);
+
+  ih->handle = (InativeHandle*)new BScrollView("scrollcanvas",
+	canvas, B_FOLLOW_LEFT | B_FOLLOW_TOP, flags, scrollh, scrollv, border);
+
+  /* configure for DRAG&DROP */
+  if (IupGetCallback(ih, "DROPFILES_CB"))
+    iupAttribSetStr(ih, "DROPFILESTARGET", "YES");
+
+  iuphaikuBaseAddToParent(ih);
+
+  iupAttribSetStr(ih, "DRAWABLE", (char*)canvas);
+
+  return IUP_NOERROR;
+}
+
+void iupdrvCanvasInitClass(Iclass* ic)
+{
+  /* Driver Dependent Class functions */
+  ic->Map = haikuCanvasMapMethod;
+  ic->LayoutUpdate = haikuCanvasLayoutUpdateMethod;
+
+  /* Driver Dependent Attribute functions */
+
+  /* Visual */
+  iupClassRegisterAttribute(ic, "BGCOLOR", NULL, gtkCanvasSetBgColorAttrib, "255 255 255", NULL, IUPAF_DEFAULT);  /* force new default value */
+
+  /* IupCanvas only */
+  iupClassRegisterAttribute(ic, "CURSOR", NULL, iupdrvBaseSetCursorAttrib, IUPAF_SAMEASSYSTEM, "ARROW", IUPAF_IHANDLENAME|IUPAF_NO_INHERIT);
+  iupClassRegisterAttribute(ic, "DRAWSIZE", gtkCanvasGetDrawSizeAttrib, NULL, NULL, NULL, IUPAF_READONLY|IUPAF_NO_INHERIT);
+
+  iupClassRegisterAttribute(ic, "DX", NULL, gtkCanvasSetDXAttrib, "0.1", NULL, IUPAF_NO_INHERIT);  /* force new default value */
+  iupClassRegisterAttribute(ic, "DY", NULL, gtkCanvasSetDYAttrib, "0.1", NULL, IUPAF_NO_INHERIT);  /* force new default value */
+  iupClassRegisterAttribute(ic, "POSX", iupCanvasGetPosXAttrib, gtkCanvasSetPosXAttrib, "0", NULL, IUPAF_NO_INHERIT);  /* force new default value */
+  iupClassRegisterAttribute(ic, "POSY", iupCanvasGetPosYAttrib, gtkCanvasSetPosYAttrib, "0", NULL, IUPAF_NO_INHERIT);  /* force new default value */
+  iupClassRegisterAttribute(ic, "XAUTOHIDE", NULL, gtkCanvasSetXAutoHideAttrib, "YES", NULL, IUPAF_DEFAULT);  /* force new default value */
+  iupClassRegisterAttribute(ic, "YAUTOHIDE", NULL, gtkCanvasSetYAutoHideAttrib, "YES", NULL, IUPAF_DEFAULT);  /* force new default value */
+
+  /* IupCanvas Windows or X only */
+#ifndef GTK_MAC
+  #ifdef WIN32                                 
+    iupClassRegisterAttribute(ic, "HWND", iupgtkGetNativeWindowHandle, NULL, NULL, NULL, IUPAF_NO_STRING|IUPAF_NO_INHERIT);
+  #else
+    iupClassRegisterAttribute(ic, "XWINDOW", iupgtkGetNativeWindowHandle, NULL, NULL, NULL, IUPAF_NO_INHERIT|IUPAF_NO_STRING);
+    iupClassRegisterAttribute(ic, "XDISPLAY", (IattribGetFunc)iupdrvGetDisplay, NULL, NULL, NULL, IUPAF_READONLY|IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT|IUPAF_NO_STRING);
+  #endif
+#endif
+
+  /* Not Supported */
+  iupClassRegisterAttribute(ic, "BACKINGSTORE", NULL, NULL, "YES", NULL, IUPAF_NOT_SUPPORTED|IUPAF_NO_INHERIT);
+  iupClassRegisterAttribute(ic, "TOUCH", NULL, NULL, NULL, NULL, IUPAF_NOT_SUPPORTED|IUPAF_NO_INHERIT);
+}
diff --git a/src/haiku/iuphaiku_clipboard.c b/src/haiku/iuphaiku_clipboard.c
new file mode 100644
index 0000000..f313b0a
--- /dev/null
+++ b/src/haiku/iuphaiku_clipboard.c
@@ -0,0 +1,122 @@
+/** \file
+ * \brief Clipboard for the GTK Driver.
+ *
+ * See Copyright Notice in "iup.h"
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <memory.h>
+
+#include "iup.h"
+
+#include "iup_object.h"
+#include "iup_attrib.h"
+#include "iup_str.h"
+#include "iup_image.h"
+
+#include "iuphaiku_drv.h"
+#define UNIMPLEMENTED printf("%s (%s %d) UNIMPLEMENTED\n",__func__,__FILE__,__LINE__);
+
+static int gtkClipboardSetFormatDataAttrib(Ihandle *ih, const char *value)
+{
+	UNIMPLEMENTED
+		return 0;
+}
+
+static char* gtkClipboardGetFormatDataAttrib(Ihandle *ih)
+{
+	UNIMPLEMENTED
+		return NULL;
+}
+
+static int gtkClipboardSetTextAttrib(Ihandle *ih, const char *value)
+{
+	UNIMPLEMENTED
+  return 0;
+}
+
+static char* gtkClipboardGetTextAttrib(Ihandle *ih)
+{
+	UNIMPLEMENTED
+		return NULL;
+}
+
+static int gtkClipboardSetImageAttrib(Ihandle *ih, const char *value)
+{
+	UNIMPLEMENTED
+		return 0;
+}
+
+static int gtkClipboardSetNativeImageAttrib(Ihandle *ih, const char *value)
+{
+	UNIMPLEMENTED
+		return 0;
+}
+
+static char* gtkClipboardGetNativeImageAttrib(Ihandle *ih)
+{
+	UNIMPLEMENTED
+		return NULL;
+}
+
+static char* gtkClipboardGetTextAvailableAttrib(Ihandle *ih)
+{
+	UNIMPLEMENTED
+		return NULL;
+}
+
+static char* gtkClipboardGetImageAvailableAttrib(Ihandle *ih)
+{
+	UNIMPLEMENTED
+		return NULL;
+}
+
+static char* gtkClipboardGetFormatAvailableAttrib(Ihandle *ih)
+{
+	UNIMPLEMENTED
+		return NULL;
+}
+
+static int gtkClipboardSetAddFormatAttrib(Ihandle *ih, const char *value)
+{
+	UNIMPLEMENTED;
+  return 0;
+}
+
+/******************************************************************************/
+
+Ihandle* IupClipboard(void)
+{
+  return IupCreate("clipboard");
+}
+
+Iclass* iupClipboardNewClass(void)
+{
+  Iclass* ic = iupClassNew(NULL);
+
+  ic->name = "clipboard";
+  ic->format = NULL;  /* no parameters */
+  ic->nativetype = IUP_TYPECONTROL;
+  ic->childtype = IUP_CHILDNONE;
+  ic->is_interactive = 0;
+
+  ic->New = iupClipboardNewClass;
+
+  /* Attribute functions */
+  iupClassRegisterAttribute(ic, "TEXT", gtkClipboardGetTextAttrib, gtkClipboardSetTextAttrib, NULL, NULL, IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT);
+  iupClassRegisterAttribute(ic, "TEXTAVAILABLE", gtkClipboardGetTextAvailableAttrib, NULL, NULL, NULL, IUPAF_READONLY|IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT);
+
+  iupClassRegisterAttribute(ic, "NATIVEIMAGE", gtkClipboardGetNativeImageAttrib, gtkClipboardSetNativeImageAttrib, NULL, NULL, IUPAF_NO_STRING|IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT);
+  iupClassRegisterAttribute(ic, "IMAGE", NULL, gtkClipboardSetImageAttrib, NULL, NULL, IUPAF_IHANDLENAME|IUPAF_WRITEONLY|IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT);
+  iupClassRegisterAttribute(ic, "IMAGEAVAILABLE", gtkClipboardGetImageAvailableAttrib, NULL, NULL, NULL, IUPAF_READONLY|IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT);
+
+  iupClassRegisterAttribute(ic, "ADDFORMAT", NULL, gtkClipboardSetAddFormatAttrib, NULL, NULL, IUPAF_WRITEONLY|IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT);
+  iupClassRegisterAttribute(ic, "FORMAT", NULL, NULL, NULL, NULL, IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT);
+  iupClassRegisterAttribute(ic, "FORMATAVAILABLE", gtkClipboardGetFormatAvailableAttrib, NULL, NULL, NULL, IUPAF_READONLY|IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT);
+  iupClassRegisterAttribute(ic, "FORMATDATA", gtkClipboardGetFormatDataAttrib, gtkClipboardSetFormatDataAttrib, NULL, NULL, IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT);
+  iupClassRegisterAttribute(ic, "FORMATDATASIZE", NULL, NULL, NULL, NULL, IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT);
+
+  return ic;
+}
diff --git a/src/haiku/iuphaiku_colordlg.c b/src/haiku/iuphaiku_colordlg.c
new file mode 100644
index 0000000..132aae1
--- /dev/null
+++ b/src/haiku/iuphaiku_colordlg.c
@@ -0,0 +1,31 @@
+/** \file
+ * \brief IupColorDlg pre-defined dialog
+ *
+ * See Copyright Notice in "iup.h"
+ */
+
+#include <string.h>
+#include <memory.h>
+#include <stdio.h>
+
+#include "iup.h"
+
+#include "iup_object.h"
+#include "iup_attrib.h"
+#include "iup_str.h"
+#include "iup_dialog.h"
+
+#include "iuphaiku_drv.h"
+
+#define UNIMPLEMENTED printf("%s (%s %d) UNIMPLEMENTED\n",__func__,__FILE__,__LINE__);
+
+static int gtkColorDlgPopup(Ihandle* ih, int x, int y)
+{
+	UNIMPLEMENTED
+  return IUP_NOERROR;
+}
+
+void iupdrvColorDlgInitClass(Iclass* ic)
+{
+  ic->DlgPopup = gtkColorDlgPopup;
+}
diff --git a/src/haiku/iuphaiku_common.cpp b/src/haiku/iuphaiku_common.cpp
new file mode 100644
index 0000000..df4b761
--- /dev/null
+++ b/src/haiku/iuphaiku_common.cpp
@@ -0,0 +1,292 @@
+/** \file
+ * \brief Haiku Base Functions
+ *
+ * See Copyright Notice in "iup.h"
+ */
+
+#include <Control.h>
+#include <ScrollBar.h>
+#include <UTF8.h>
+#include <Window.h>
+
+#include <stdio.h>              
+#include <stdlib.h>
+#include <string.h>             
+#include <limits.h>             
+
+#include "iup.h"
+#include "iupcbs.h"
+#include "iupkey.h"
+
+#include "iup_object.h"
+#include "iup_childtree.h"
+#include "iup_key.h"
+#include "iup_str.h"
+#include "iup_class.h"
+#include "iup_attrib.h"
+#include "iup_focus.h"
+#include "iup_key.h"
+#include "iup_image.h"
+#include "iup_drv.h"
+
+#include "iuphaiku_drv.h"
+
+#define UNIMPLEMENTED printf("%s (%s %d) UNIMPLEMENTED\n",__func__,__FILE__,__LINE__);
+
+void iupgtkUpdateMnemonic(Ihandle* ih)
+{
+	UNIMPLEMENTED
+}
+
+void iupdrvActivate(Ihandle* ih)
+{
+	UNIMPLEMENTED
+}
+
+void iupdrvReparent(Ihandle* ih)
+{
+	UNIMPLEMENTED
+}
+
+
+BView* viewFromHandler(BHandler* handler)
+{
+	BWindow* window = dynamic_cast<BWindow*>(handler);
+	if (window)
+	  return window->ChildAt(0); // Get background view
+	else
+   	  return dynamic_cast<BView*>(handler);
+}
+
+
+void iuphaikuBaseAddToParent(Ihandle* ih)
+{
+	BHandler* parent = (BHandler*)iupChildTreeGetNativeParentHandle(ih);
+	BView* child = (BView*)ih->handle;
+
+	BView* view = viewFromHandler(parent);
+	if(view)
+	  view->AddChild(child);
+	else
+	  debugger("Trying to add a control to a parent that has no BView");
+}
+
+void iupdrvBaseLayoutUpdateMethod(Ihandle *ih)
+{
+	BView* view = (BView*)ih->handle;
+	view->MoveTo(ih->x, ih->y);
+	view->ResizeTo(ih->currentwidth, ih->currentheight);
+}
+
+void iupdrvBaseUnMapMethod(Ihandle* ih)
+{
+  BHandler* handler = (BHandler*)ih->handle;
+  BView* view = dynamic_cast<BView*>(handler);
+  BWindow* window = dynamic_cast<BWindow*>(handler);
+  if(view) {
+	view->RemoveSelf();
+    delete view;
+  } else if(window) {
+    window->Quit();
+	// The window will delete itself
+  } else if(handler != NULL)
+    UNIMPLEMENTED
+}
+
+void iupdrvPostRedraw(Ihandle *ih)
+{
+	UNIMPLEMENTED
+}
+
+void iupdrvRedrawNow(Ihandle *ih)
+{
+	UNIMPLEMENTED
+}
+
+void iupdrvScreenToClient(Ihandle* ih, int *x, int *y)
+{
+	UNIMPLEMENTED
+}
+
+void iupdrvClientToScreen(Ihandle* ih, int *x, int *y)
+{
+	UNIMPLEMENTED
+}
+
+int iupdrvBaseSetZorderAttrib(Ihandle* ih, const char* value)
+{
+	UNIMPLEMENTED
+	return 0;
+}
+
+void iupdrvSetVisible(Ihandle* ih, int visible)
+{
+  BView* view = (BView*)ih->handle;
+  if(visible && view->IsHidden())
+    view->Show();
+  else if(!visible && !view->IsHidden())
+	view->Hide();
+}
+
+int iupdrvIsVisible(Ihandle* ih)
+{
+  BView* view = (BView*)ih->handle;
+  return !view->IsHidden();
+}
+
+int iupdrvIsActive(Ihandle *ih)
+{
+	BHandler* handler = (BHandler*)ih->handle;
+
+	BControl* control = dynamic_cast<BControl*>(handler);
+	if (control && !control->IsEnabled())
+	  return false;
+	return true;
+}
+
+void iupdrvSetActive(Ihandle* ih, int enable)
+{
+	BHandler* handler = (BHandler*)ih->handle;
+
+	BView* view = dynamic_cast<BView*>(handler);
+	BWindow* window = dynamic_cast<BWindow*>(handler);
+	if (view)
+	  view->MakeFocus(enable);
+	if (window)
+	  window->Activate(enable);
+}
+
+void iuphaikuBaseSetBgColor(InativeHandle* handle, unsigned char r, unsigned char g, unsigned char b)
+{
+  BView* view = viewFromHandler((BHandler*)handle);
+
+  view->SetLowColor(r,g,b);
+  view->SetViewColor(r,g,b);
+}
+
+void iuphaikuBaseSetFgColor(InativeHandle* handle, unsigned char r, unsigned char g, unsigned char b)
+{
+  BView* view = viewFromHandler((BHandler*)handle);
+
+  view->SetHighColor(r,g,b);
+}
+
+int iupdrvBaseSetBgColorAttrib(Ihandle* ih, const char* value)
+{
+  unsigned char r, g, b;
+  if (!iupStrToRGB(value, &r, &g, &b))
+    return 0;
+
+  iuphaikuBaseSetBgColor(ih->handle, r, g, b);
+
+  /* DO NOT NEED TO UPDATE GTK IMAGES SINCE THEY DO NOT DEPEND ON BGCOLOR */
+
+  return 1;
+}
+
+int iupdrvBaseSetFgColorAttrib(Ihandle* ih, const char* value)
+{
+  unsigned char r, g, b;
+  if (!iupStrToRGB(value, &r, &g, &b))
+    return 0;
+
+  iuphaikuBaseSetFgColor(ih->handle, r, g, b);
+
+  return 1;
+}
+
+int iupdrvBaseSetCursorAttrib(Ihandle* ih, const char* value)
+{
+	UNIMPLEMENTED
+  return 0;
+}
+
+int iupdrvGetScrollbarSize(void)
+{
+  return (int)B_V_SCROLL_BAR_WIDTH;
+}
+
+void iupdrvDrawFocusRect(Ihandle* ih, void* _gc, int x, int y, int w, int h)
+{
+	UNIMPLEMENTED
+}
+
+void iupdrvBaseRegisterCommonAttrib(Iclass* ic)
+{
+  // Other drivers seems to register some info about fonts and tooltips here.
+  // I'm not sure what is needed and there is no documentation...
+  iupClassRegisterAttribute(ic, "TIPMARKUP", NULL, NULL, IUPAF_SAMEASSYSTEM, NULL, IUPAF_NOT_MAPPED);
+  iupClassRegisterAttribute(ic, "TIPICON", NULL, NULL, IUPAF_SAMEASSYSTEM, NULL, IUPAF_NOT_MAPPED);
+}
+
+void iupgtkReleaseConvertUTF8(void)
+{
+	UNIMPLEMENTED
+}
+
+char* iuphaikuStrConvertToUTF8(const char* str)  /* From IUP to GTK */
+{
+  if (!str || *str == 0)
+    return (char*)str;
+
+  if (iupgtk_utf8autoconvert)  /* this means str is in current locale */
+  {
+    static char* buffer = NULL;
+    int32 len = strlen(str);
+	int32 len2 = 2 * len;
+	int32 cookie;
+	free(buffer);
+	buffer = (char*)malloc(len * 2); // Should be enough in most cases ?
+    convert_to_utf8(B_ISO9_CONVERSION, str, &len, buffer, &len2, &cookie);
+    return buffer;
+  }
+
+  return (char*)str;
+}
+
+char* iuphaikuStrConvertFromUTF8(const char* str)  /* From GTK to IUP */
+{
+  if (!str || *str == 0)
+    return (char*)str;
+
+  if (iupgtk_utf8autoconvert)  /* this means str is in current locale */
+  {
+    static char* buffer = NULL;
+    int32 len = strlen(str);
+	int32 len2 = 2 * len;
+	int32 cookie;
+	free(buffer);
+	buffer = (char*)malloc(len * 2); // Should be enough in most cases ?
+    convert_from_utf8(B_ISO9_CONVERSION, str, &len, buffer, &len2, &cookie);
+    return buffer;
+  }
+
+  return (char*)str;
+}
+
+char* iupgtkStrConvertFromFilename(const char* str)   /* From Filename to IUP */
+{
+	UNIMPLEMENTED
+  return (char*)str;
+}
+
+void iupdrvSendKey(int key, int press)
+{
+	UNIMPLEMENTED
+}
+
+void iupdrvWarpPointer(int x, int y)
+{
+	UNIMPLEMENTED
+}
+
+void iupdrvSendMouse(int x, int y, int bt, int status)
+{
+	UNIMPLEMENTED
+}
+
+void iupdrvSleep(int time)
+{
+	UNIMPLEMENTED
+}
+
diff --git a/src/haiku/iuphaiku_dialog.cpp b/src/haiku/iuphaiku_dialog.cpp
new file mode 100644
index 0000000..f679f03
--- /dev/null
+++ b/src/haiku/iuphaiku_dialog.cpp
@@ -0,0 +1,367 @@
+/** \file
+ * \brief IupDialog class
+ *
+ * See Copyright Notice in "iup.h"
+ */
+
+#include <Rect.h>
+#include <Screen.h>
+#include <Window.h>
+                                         
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <memory.h>
+#include <stdarg.h>
+#include <limits.h>
+#include <time.h>
+
+#include "iup.h"
+#include "iupcbs.h"
+
+#include "iup_class.h"
+#include "iup_object.h"
+#include "iup_layout.h"
+#include "iup_dlglist.h"
+#include "iup_attrib.h"
+#include "iup_drv.h"
+#include "iup_drvfont.h"
+#include "iup_drvinfo.h"
+#include "iup_focus.h"
+#include "iup_str.h"
+#define _IUPDLG_PRIVATE
+#include "iup_dialog.h"
+#include "iup_image.h"
+
+#include "iuphaiku_drv.h"
+
+#define UNIMPLEMENTED printf("%s (%s %d) UNIMPLEMENTED\n",__func__,__FILE__,__LINE__);
+
+/****************************************************************
+                     Utilities
+****************************************************************/
+
+int iupdrvDialogIsVisible(Ihandle* ih)
+{
+  BWindow* win = (BWindow*)ih->handle;
+  return !win->IsHidden();
+}
+
+void iupdrvDialogGetSize(Ihandle* ih, InativeHandle* handle, int *w, int *h)
+{
+  BWindow* window = (BWindow*)ih->handle;
+  BRect bounds = window->Bounds();
+
+  if(w) *w = (int)bounds.right;
+  if(h) *h = (int)bounds.bottom;
+}
+
+void iupdrvDialogSetVisible(Ihandle* ih, int visible)
+{
+  BHandler* handler = (BHandler*)ih->handle;
+  BWindow* window = dynamic_cast<BWindow*>(handler);
+  if(window) {
+    if(visible)
+      window->Show();
+    else
+	  window->Hide();
+	return;
+  }
+
+  // TODO We can get there even though the window is already destroyed...
+}
+
+void iupdrvDialogGetPosition(Ihandle *ih, InativeHandle* handle, int *x, int *y)
+{
+	UNIMPLEMENTED
+}
+
+void iupdrvDialogSetPosition(Ihandle *ih, int x, int y)
+{
+	BWindow* window = (BWindow*)ih->handle;
+	window->MoveTo(x, y);
+}
+
+static int gtkDialogGetMenuSize(Ihandle* ih)
+{
+  if (ih->data->menu && !iupgtk_globalmenu)
+    return iupdrvMenuGetMenuBarSize(ih->data->menu);
+  else
+    return 0;
+}
+
+static void gtkDialogGetWindowDecor(Ihandle* ih, int *win_border, int *win_caption)
+{
+	UNIMPLEMENTED
+}
+
+void iupdrvDialogGetDecoration(Ihandle* ih, int *border, int *caption, int *menu)
+{
+  static int native_border = 0;
+  static int native_caption = 0;
+
+  int has_titlebar = iupAttribGetBoolean(ih, "RESIZE")  || /* GTK and Motif only */
+                     iupAttribGetBoolean(ih, "MAXBOX")  ||
+                     iupAttribGetBoolean(ih, "MINBOX")  ||
+                     iupAttribGetBoolean(ih, "MENUBOX") || 
+                     IupGetAttribute(ih, "TITLE"); /* must use IupGetAttribute to check from the native implementation */
+
+  int has_border = has_titlebar ||
+                   iupAttribGetBoolean(ih, "RESIZE") ||
+                   iupAttribGetBoolean(ih, "BORDER");
+
+  *menu = gtkDialogGetMenuSize(ih);
+
+  if (ih->handle && iupdrvIsVisible(ih))
+  {
+    int win_border, win_caption;
+    gtkDialogGetWindowDecor(ih, &win_border, &win_caption);
+
+#ifdef WIN32
+    if (*menu)
+      win_caption -= *menu;
+#endif
+
+    if (!native_border && *border)
+      native_border = win_border;
+
+    if (!native_caption && *caption)
+      native_caption = win_caption;
+  }
+
+  // In Haiku, we don't need to worry about the borders when sizing a window.
+  // They are not part of the stuff we resize. So just tell IUP that the
+  // border uses no space at all.
+  *border = 0;
+  *caption = 0;
+}
+
+int iupdrvDialogSetPlacement(Ihandle* ih)
+{
+  char* placement;
+  int old_state = ih->data->show_state;
+  ih->data->show_state = IUP_SHOW;
+
+  BWindow* window = (BWindow*)ih->handle;
+
+  if (iupAttribGetBoolean(ih, "FULLSCREEN"))
+  {
+	  UNIMPLEMENTED
+    return 1;
+  }
+  
+  placement = iupAttribGet(ih, "PLACEMENT");
+  if (!placement)
+  {
+    if (old_state == IUP_MAXIMIZE || old_state == IUP_MINIMIZE)
+      ih->data->show_state = IUP_RESTORE;
+
+	window->ResizeTo(ih->naturalwidth, ih->naturalheight);
+    return 0;
+  }
+
+  if (iupStrEqualNoCase(placement, "MINIMIZED"))
+  {
+    ih->data->show_state = IUP_MINIMIZE;
+	UNIMPLEMENTED
+  }
+  else if (iupStrEqualNoCase(placement, "MAXIMIZED"))
+  {
+    int width, height, x, y;
+    int border, caption, menu;
+    iupdrvDialogGetDecoration(ih, &border, &caption, &menu);
+
+    x = (border);
+    y = (border+caption+menu);
+
+    iupdrvGetFullSize(&width, &height);
+    height += menu; /* menu is inside the client area. */
+
+	height -= y + border;
+	width -= border * 2;
+
+    ih->data->show_state = IUP_MAXIMIZE;
+
+	window->ResizeTo(width, height);
+	window->MoveTo(x, y);
+  }
+  else if (iupStrEqualNoCase(placement, "FULL"))
+  {
+	BScreen scr(window);
+	BRect frame = scr.Frame();
+
+	window->ResizeTo(frame.Width(), frame.Height());
+	window->MoveTo(frame.left, frame.top);
+
+    if (old_state == IUP_MAXIMIZE || old_state == IUP_MINIMIZE)
+      ih->data->show_state = IUP_RESTORE;
+  }
+
+  iupAttribSetStr(ih, "PLACEMENT", NULL); /* reset to NORMAL */
+
+  return 1;
+}
+
+
+static int beDialogSetTitleAttrib(Ihandle* ih, const char* value)
+{
+  if (!value)
+    value = "";
+
+  BWindow* window = (BWindow*)ih->handle;
+  window->SetTitle(value);
+
+  return 0;
+}
+
+static char* beDialogGetTitleAttrib(Ihandle* ih)
+{
+  BWindow* window = (BWindow*)ih->handle;
+  const char* title = window->Title();
+
+  if (!title || title[0] == 0)
+    return NULL;
+  else
+    return iupStrGetMemoryCopy(title);
+}    
+
+/****************************************************************
+                     Idialog Methods
+****************************************************************/
+
+// TODO these could be IUPWindow static private methods ?
+extern void iuphaikuListInvoked(Ihandle* ih, int item);
+extern void iuphaikuToggleInvoked(Ihandle* ih, int value);
+extern void iuphaikuButtonInvoked(Ihandle* ih);
+extern void iuphaikuListSelected(Ihandle* ih, int item);
+
+// This one also used at BApplication level
+extern void iuphaikuTimerFired(Ihandle* ih);
+
+class IUPWindow: public BWindow
+{
+  private:
+	  Ihandle* myHandle;
+  public:
+	
+  IUPWindow(Ihandle* ih)
+	: BWindow(BRect(100,100,200,200), "", B_TITLED_WINDOW, 0)
+  {
+	this->myHandle = ih;
+	BView* view = new BView(Bounds(), "background",B_FOLLOW_ALL_SIDES, 0);
+	view->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
+	AddChild(view);
+  }
+
+  void MessageReceived(BMessage* message)
+  {
+	Ihandle* ih = NULL;
+	int32 index = 0;
+
+	message->FindPointer("iHandle", (void**)&ih);
+
+	switch(message->what)
+	{
+	  case checkboxInvoke:
+		message->FindInt32("be:value", &index);
+		iuphaikuToggleInvoked(ih, index);
+		break;
+	  case listInvoke:
+		message->FindInt32("index", &index);
+		iuphaikuListInvoked(ih, index);
+		break;
+	  case listSelect:
+		message->FindInt32("index", &index);
+		iuphaikuListSelected(ih, index);
+		break;
+	  case buttonInvoke:
+	  case menuInvoke:
+		iuphaikuButtonInvoked(ih);
+		break;
+	  case timerFire:
+		iuphaikuTimerFired(ih);
+		break;
+      default:
+		BWindow::MessageReceived(message);
+	}
+  }
+
+  bool QuitRequested()
+  {
+    Icallback cb = IupGetCallback(myHandle, "CLOSE_CB");
+    if (cb)
+    {
+      int ret = cb(myHandle);
+      if (ret == IUP_IGNORE)
+        return false;
+      if (ret == IUP_CLOSE)
+        return true;
+	}
+
+	return true;
+  }
+};
+
+
+static int beDialogMapMethod(Ihandle* ih)
+{
+  ih->handle = (InativeHandle*)new IUPWindow(ih);
+  return IUP_NOERROR;
+}
+
+
+/* replace the common dialog SetChildrenPosition method because of 
+   the menu that it is inside the dialog. */
+static void beDialogSetChildrenPositionMethod(Ihandle* ih, int x, int y)
+{
+  int menu_h = gtkDialogGetMenuSize(ih);
+  (void)x;
+  (void)y;
+
+  /* Child coordinates are relative to client left-top corner. */
+  iupBaseSetPosition(ih->firstchild, 0, menu_h);
+}
+
+/****************************************************************************
+                                   Attributes
+****************************************************************************/
+
+void iupdrvDialogInitClass(Iclass* ic)
+{
+	ic->Map = beDialogMapMethod;
+	/*
+	ic->UnMap = beDialogUnMapMethod;
+	ic->LayoutUpdate = beDialogLayoutUpdateMethod;
+	ic->GetInnerNativeContainerHandle = beDialogGetInnerNativeContainerHandleMethod;
+	*/
+	ic->SetChildrenPosition = beDialogSetChildrenPositionMethod;
+	
+	// Register TRAYCLICK_CB callback
+	
+	// Set platform-specific handlers
+	// HWND/XWINDOW > Get native BWindow pointer
+	// CLIENTSIZE > window size
+	// CLIENTOFFSET > window position
+	
+  /* Visual */
+  iupClassRegisterAttribute(ic, "BGCOLOR", NULL, iupdrvBaseSetBgColorAttrib, "DLGBGCOLOR", NULL, IUPAF_DEFAULT);  /* force new default value */
+
+  /* Special */
+  iupClassRegisterAttribute(ic, "TITLE", beDialogGetTitleAttrib, beDialogSetTitleAttrib,
+	NULL, NULL, IUPAF_NO_DEFAULTVALUE|IUPAF_NO_INHERIT);
+
+	// BACKGROUND
+	// ICON
+	// FULLSCREEN
+	// MINSIZE
+	// MAXSIZE
+	// SAVEUNDER ?
+	// ACTIVEWINDOW
+	// TOPMOST
+	// DIALOGHINT
+	// OPACITY
+	// TRAY
+	// TRAYIMAGE
+	// TRAYTIP
+	// TRAYTIPMARKUP
+}
diff --git a/src/haiku/iuphaiku_dragdrop.c b/src/haiku/iuphaiku_dragdrop.c
new file mode 100644
index 0000000..441f027
--- /dev/null
+++ b/src/haiku/iuphaiku_dragdrop.c
@@ -0,0 +1,94 @@
+/** \file
+ * \brief GTK Drag&Drop Functions
+ *
+ * See Copyright Notice in "iup.h"
+ */
+
+#include <stdio.h>              
+#include <stdlib.h>
+#include <string.h>             
+#include <limits.h>             
+
+#include "iup.h"
+#include "iupcbs.h"
+
+#include "iup_object.h"
+#include "iup_str.h"
+#include "iup_class.h"
+#include "iup_attrib.h"
+#include "iup_drv.h"
+#include "iup_key.h"
+
+#include "iuphaiku_drv.h"
+
+#define UNIMPLEMENTED printf("%s (%s %d) UNIMPLEMENTED\n",__func__,__FILE__,__LINE__);
+
+/******************************************************************************************/
+
+
+static int gtkSetDropTypesAttrib(Ihandle* ih, const char* value)
+{
+	UNIMPLEMENTED
+  return 1;
+}
+
+static int gtkSetDropTargetAttrib(Ihandle* ih, const char* value)
+{
+	UNIMPLEMENTED
+  return 1;
+}
+
+static int gtkSetDragTypesAttrib(Ihandle* ih, const char* value)
+{
+	UNIMPLEMENTED
+  return 1;
+}
+
+static int gtkSetDragSourceAttrib(Ihandle* ih, const char* value)
+{
+	UNIMPLEMENTED
+  return 1;
+}
+
+
+/******************************************************************************************/
+
+
+static int gtkSetDropFilesTargetAttrib(Ihandle* ih, const char* value)
+{
+	UNIMPLEMENTED
+  return 1;
+}
+
+
+/******************************************************************************************/
+
+
+void iupdrvRegisterDragDropAttrib(Iclass* ic)
+{
+  iupClassRegisterCallback(ic, "DROPFILES_CB", "siii");
+
+  iupClassRegisterCallback(ic, "DRAGBEGIN_CB", "ii");
+  iupClassRegisterCallback(ic, "DRAGDATASIZE_CB", "s");
+  iupClassRegisterCallback(ic, "DRAGDATA_CB", "sCi");
+  iupClassRegisterCallback(ic, "DRAGEND_CB", "i");
+  iupClassRegisterCallback(ic, "DROPDATA_CB", "sCiii");
+  iupClassRegisterCallback(ic, "DROPMOTION_CB", "iis");
+
+  iupClassRegisterAttribute(ic, "DRAGTYPES",  NULL, gtkSetDragTypesAttrib,  NULL, NULL, IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT);
+  iupClassRegisterAttribute(ic, "DROPTYPES",  NULL, gtkSetDropTypesAttrib,  NULL, NULL, IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT);
+  iupClassRegisterAttribute(ic, "DRAGSOURCE", NULL, gtkSetDragSourceAttrib, NULL, NULL, IUPAF_NO_INHERIT);
+  iupClassRegisterAttribute(ic, "DROPTARGET", NULL, gtkSetDropTargetAttrib, NULL, NULL, IUPAF_NO_INHERIT);
+  iupClassRegisterAttribute(ic, "DRAGSOURCEMOVE", NULL, NULL, NULL, NULL, IUPAF_NO_INHERIT);
+
+  iupClassRegisterAttribute(ic, "DRAGDROP", NULL, gtkSetDropFilesTargetAttrib, NULL, NULL, IUPAF_NO_INHERIT);
+  iupClassRegisterAttribute(ic, "DROPFILESTARGET", NULL, gtkSetDropFilesTargetAttrib, NULL, NULL, IUPAF_NO_INHERIT);
+}
+
+/* TODO:
+  Could not find a way to disable the internal DND support 
+  in IupText(GtkTextView or GtkEntry).
+  Mixing the generic support from here and the internal gives weird results.
+  So the application should use only the internal in this case.
+  The edit box in a IupList has the same problem.
+*/
diff --git a/src/haiku/iuphaiku_draw.c b/src/haiku/iuphaiku_draw.c
new file mode 100644
index 0000000..f24206f
--- /dev/null
+++ b/src/haiku/iuphaiku_draw.c
@@ -0,0 +1,127 @@
+/** \file
+ * \brief Draw Functions
+ *
+ * See Copyright Notice in "iup.h"
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <memory.h>
+
+#define UNIMPLEMENTED printf("%s (%s %d) UNIMPLEMENTED\n",__func__,__FILE__,__LINE__);
+
+#include "iup.h"
+
+#include "iup_attrib.h"
+#include "iup_class.h"
+#include "iup_str.h"
+#include "iup_object.h"
+#include "iup_image.h"
+#include "iup_draw.h"
+
+#include "iuphaiku_drv.h"
+
+
+struct _IdrawCanvas{
+  Ihandle* ih;
+  int w, h;
+
+  /*
+  GdkDrawable* wnd;
+  GdkPixmap* pixmap;
+  GdkGC *gc, *pixmap_gc;
+  */
+};
+
+IdrawCanvas* iupDrawCreateCanvas(Ihandle* ih)
+{
+  IdrawCanvas* dc = calloc(1, sizeof(IdrawCanvas));
+
+  dc->ih = ih;
+
+UNIMPLEMENTED
+
+  return dc;
+}
+
+void iupDrawKillCanvas(IdrawCanvas* dc)
+{
+UNIMPLEMENTED
+
+  free(dc);
+}
+
+void iupDrawUpdateSize(IdrawCanvas* dc)
+{
+UNIMPLEMENTED
+}
+
+void iupDrawFlush(IdrawCanvas* dc)
+{
+UNIMPLEMENTED
+}
+
+void iupDrawGetSize(IdrawCanvas* dc, int *w, int *h)
+{
+  if (w) *w = dc->w;
+  if (h) *h = dc->h;
+}
+
+void iupDrawParentBackground(IdrawCanvas* dc)
+{
+  unsigned char r=0, g=0, b=0;
+  char* color = iupBaseNativeParentGetBgColorAttrib(dc->ih);
+  iupStrToRGB(color, &r, &g, &b);
+  iupDrawRectangle(dc, 0, 0, dc->w-1, dc->h-1, r, g, b, IUP_DRAW_FILL);
+}
+
+void iupDrawRectangle(IdrawCanvas* dc, int x1, int y1, int x2, int y2, unsigned char r, unsigned char g, unsigned char b, int style)
+{
+	UNIMPLEMENTED
+}
+
+void iupDrawLine(IdrawCanvas* dc, int x1, int y1, int x2, int y2, unsigned char r, unsigned char g, unsigned char b, int style)
+{
+	UNIMPLEMENTED
+}
+
+void iupDrawArc(IdrawCanvas* dc, int x1, int y1, int x2, int y2, double a1, double a2, unsigned char r, unsigned char g, unsigned char b, int style)
+{
+	UNIMPLEMENTED
+}
+
+void iupDrawPolygon(IdrawCanvas* dc, int* points, int count, unsigned char r, unsigned char g, unsigned char b, int style)
+{
+	UNIMPLEMENTED
+}
+
+void iupDrawSetClipRect(IdrawCanvas* dc, int x1, int y1, int x2, int y2)
+{
+	UNIMPLEMENTED
+}
+
+void iupDrawResetClip(IdrawCanvas* dc)
+{
+	UNIMPLEMENTED
+}
+
+void iupDrawText(IdrawCanvas* dc, const char* text, int len, int x, int y, unsigned char r, unsigned char g, unsigned char b, const char* font)
+{
+	UNIMPLEMENTED
+}
+
+void iupDrawImage(IdrawCanvas* dc, const char* name, int make_inactive, int x, int y, int *img_w, int *img_h)
+{
+	UNIMPLEMENTED
+}
+
+void iupDrawSelectRect(IdrawCanvas* dc, int x, int y, int w, int h)
+{
+	UNIMPLEMENTED
+}
+
+void iupDrawFocusRect(IdrawCanvas* dc, int x, int y, int w, int h)
+{
+	UNIMPLEMENTED
+}
diff --git a/src/haiku/iuphaiku_drv.h b/src/haiku/iuphaiku_drv.h
new file mode 100644
index 0000000..9668517
--- /dev/null
+++ b/src/haiku/iuphaiku_drv.h
@@ -0,0 +1,72 @@
+/** \file
+ * \brief GTK Driver 
+ *
+ * See Copyright Notice in "iup.h"
+ */
+ 
+#ifndef __IUPGTK_DRV_H 
+#define __IUPGTK_DRV_H
+
+
+#ifdef __cplusplus
+class BView;
+class BHandler;
+
+BView* viewFromHandler(BHandler* handler);
+
+extern "C" {
+#endif
+
+#define iupCOLORDoubleTO8(_x) ((unsigned char)(_x*255))  /* 1.0*255 = 255 */
+#define iupCOLOR8ToDouble(_x) ((double)_x/255.0)
+
+
+/* global variables, declared in iupgtk_globalattrib.c */
+extern int iupgtk_utf8autoconvert;         
+extern int iupgtk_globalmenu;
+
+
+/* common */
+void iuphaikuBaseAddToParent(Ihandle* ih);
+char* iuphaikuStrConvertToUTF8(const char* str);
+char* iuphaikuStrConvertFromUTF8(const char* str);
+void iupgtkReleaseConvertUTF8(void);
+char* iupgtkStrConvertFromFilename(const char* str);
+char* iupgtkStrConvertToFilename(const char* str);
+void iupgtkUpdateMnemonic(Ihandle* ih);
+void iuphaikuBaseSetBgColor(InativeHandle* handle, unsigned char r, unsigned char g, unsigned char b);
+void iuphaikuBaseSetFgColor(InativeHandle* handle, unsigned char r, unsigned char g, unsigned char b);
+
+
+/* key */
+
+/* font */
+char* iupgtkGetPangoFontDescAttrib(Ihandle *ih);
+char* iupgtkGetPangoLayoutAttrib(Ihandle *ih);
+char* iupgtkGetFontIdAttrib(Ihandle *ih);
+
+/* There are PANGO_SCALE Pango units in one device unit. 
+  For an output backend where a device unit is a pixel, 
+  a size value of 10 * PANGO_SCALE gives 10 pixels. */
+#define iupGTK_PANGOUNITS2PIXELS(_x) (((_x) + PANGO_SCALE/2) / PANGO_SCALE)
+#define iupGTK_PIXELS2PANGOUNITS(_x) ((_x) * PANGO_SCALE)
+
+
+/* open */
+char* iupgtkGetNativeWindowHandle(Ihandle* ih);
+void iupgtkPushVisualAndColormap(void* visual, void* colormap);
+
+enum messageConstants {
+  buttonInvoke   = 'buti',
+  checkboxInvoke = 'cbxi',
+  listInvoke     = 'linv',
+  listSelect     = 'lsel',
+  menuInvoke     = 'meni',
+  timerFire      = 'time',
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/haiku/iuphaiku_filedlg.cpp b/src/haiku/iuphaiku_filedlg.cpp
new file mode 100644
index 0000000..c6f197a
--- /dev/null
+++ b/src/haiku/iuphaiku_filedlg.cpp
@@ -0,0 +1,221 @@
+/** \file
+ * \brief IupFileDlg pre-defined dialog
+ *
+ * See Copyright Notice in "iup.h"
+ */
+
+#define UNIMPLEMENTED printf("%s (%s %d) UNIMPLEMENTED\n",__func__,__FILE__,__LINE__);
+
+#include <stdlib.h>
+#include <string.h>
+#include <memory.h>
+#include <stdio.h>
+
+#include <FilePanel.h>
+#include <Looper.h>
+#include <Messenger.h>
+#include <Path.h>
+#include <Window.h>
+
+#include "iup.h"
+#include "iupcbs.h"
+
+#include "iup_object.h"
+#include "iup_attrib.h"
+#include "iup_str.h"
+#include "iup_drvinfo.h"
+#include "iup_dialog.h"
+#include "iup_strmessage.h"
+#include "iup_array.h"
+#include "iup_drvinfo.h"
+
+#include "iuphaiku_drv.h"
+
+
+class FileHandler: public BLooper
+{
+	public:
+
+	FileHandler()
+		: BLooper("filepanel listener")
+	{
+		lock = create_sem(0, "filepanel sem");
+		path = NULL;
+
+		Run();
+	}
+
+	~FileHandler()
+	{
+		delete_sem(lock);
+		free(path);
+	}
+
+	void MessageReceived(BMessage* message)
+	{
+		switch(message->what)
+		{
+			case B_REFS_RECEIVED:
+			{
+				entry_ref ref;
+
+				message->FindRef("refs", 0, &ref);
+				BEntry entry(&ref);
+				BPath xpath;
+				entry.GetPath(&xpath);
+				path = strdup(xpath.Path());
+				break;
+			}
+
+			case B_SAVE_REQUESTED:
+			{
+				entry_ref ref;
+
+				message->FindRef("directory", 0, &ref);
+				BEntry entry(&ref);
+				BPath xpath;
+				entry.GetPath(&xpath);
+				const char* dir = xpath.Path();
+
+				const char* name;
+			    message->FindString("name", 0, &name);
+				path = (char*)malloc(strlen(name) + strlen(dir) + 1);
+				strcpy(path, dir);
+				strcat(path, name);
+				break;
+			}
+
+			case B_CANCEL:
+			{
+				// If the path was set, do not change it.
+				// If it was not set, leave it null and HT will not load anything
+				break;
+			}
+
+			default:
+				printf("Unhandled message %lx\n", message->what);
+				BHandler::MessageReceived(message);
+				return;
+		}
+
+		release_sem(lock);
+	}
+
+	void Wait() {
+		acquire_sem(lock);
+	}
+
+	char* path;
+
+	private:
+		sem_id lock;
+};
+
+static int gtkFileDlgPopup(Ihandle* ih, int x, int y)
+{
+  file_panel_mode mode;
+  uint32 flavour;
+  char* value = iupAttribGetStr(ih, "DIALOGTYPE");
+  if (iupStrEqualNoCase(value, "SAVE"))
+    mode = B_SAVE_PANEL;
+  else {
+    mode = B_OPEN_PANEL;
+	if (iupStrEqualNoCase(value, "DIR"))
+	  flavour = B_DIRECTORY_NODE;
+    else
+	  flavour = B_FILE_NODE;
+  }
+
+  
+  //if (IupGetCallback(ih, "HELP_CB"))
+  //if (iupAttribGetBoolean(ih, "MULTIPLEFILES") && action == GTK_FILE_CHOOSER_ACTION_OPEN)
+  //if (!iupAttribGetBoolean(ih, "NOOVERWRITEPROMPT") && action == GTK_FILE_CHOOSER_ACTION_SAVE)
+
+  FileHandler* handler = new FileHandler();
+  BMessenger messenger(handler);
+  BFilePanel* panel = new BFilePanel(mode, &messenger, NULL, flavour);
+  
+  /* just check for the path inside FILE */
+  value = iupAttribGet(ih, "FILE");
+  if (value && (value[0] == '/' || value[1] == ':'))
+  {
+    char* dir = iupStrFileGetPath(value);
+    int len = strlen(dir);
+    iupAttribStoreStr(ih, "DIRECTORY", dir);
+    free(dir);
+    iupAttribStoreStr(ih, "FILE", value+len);
+  }
+
+  value = iupAttribGet(ih, "DIRECTORY");
+  if (value)
+    panel->SetPanelDirectory(new BDirectory(value));
+    //iupgtkStrConvertToFilename(value);
+  value = iupAttribGet(ih, "FILE");
+  // TODO preset the textfield with the file name
+  
+  value = iupAttribGet(ih, "TITLE");
+  BWindow* win = panel->Window();
+  win->LockLooper();
+  win->SetTitle(value);
+  win->UnlockLooper();
+  
+  //value = iupAttribGet(ih, "EXTFILTER");
+    //value = iupAttribGet(ih, "FILTER");
+    //char* info = iupAttribGet(ih, "FILTERINFO");
+  
+  //file_cb = (IFnss)IupGetCallback(ih, "FILE_CB");
+  //if (iupAttribGetBoolean(ih, "SHOWPREVIEW"))
+
+  panel->Show();
+  handler->Wait();
+  delete panel;
+
+  if (iupAttribGetBoolean(ih, "MULTIPLEFILES"))
+	UNIMPLEMENTED
+
+  iupAttribStoreStr(ih, "VALUE", handler->path);
+
+  int file_exist = iupdrvIsFile(handler->path);
+  int dir_exist = iupdrvIsDirectory(handler->path);
+  
+  if (file_exist)
+  {
+    char* dir = iupStrFileGetPath(handler->path);
+    iupAttribStoreStr(ih, "DIRECTORY", dir);
+    free(dir);
+  }
+
+  if (dir_exist)
+  {
+    iupAttribSetStr(ih, "FILEEXIST", NULL);
+    iupAttribSetStr(ih, "STATUS", "0");
+  }
+  else
+  {
+    if (file_exist)  /* check if file exists */
+    {
+      iupAttribSetStr(ih, "FILEEXIST", "YES");
+      iupAttribSetStr(ih, "STATUS", "0");
+    }
+    else
+    {
+      iupAttribSetStr(ih, "FILEEXIST", "NO");
+      iupAttribSetStr(ih, "STATUS", "1");
+    }
+  }
+  // put results
+  //if (action != GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER && !iupAttribGetBoolean(ih, "NOCHANGEDIR"))  /* do change the current directory */
+  messenger.SendMessage(B_QUIT_REQUESTED);
+  return IUP_NOERROR;
+}
+
+extern "C" void iupdrvFileDlgInitClass(Iclass* ic)
+{
+  ic->DlgPopup = gtkFileDlgPopup;
+
+  /* IupFileDialog Windows and GTK Only */
+  iupClassRegisterAttribute(ic, "EXTFILTER", NULL, NULL, NULL, NULL, IUPAF_NO_INHERIT);
+  iupClassRegisterAttribute(ic, "FILTERINFO", NULL, NULL, NULL, NULL, IUPAF_NO_INHERIT);
+  iupClassRegisterAttribute(ic, "FILTERUSED", NULL, NULL, NULL, NULL, IUPAF_NO_INHERIT);
+  iupClassRegisterAttribute(ic, "MULTIPLEFILES", NULL, NULL, NULL, NULL, IUPAF_NO_INHERIT);
+}
diff --git a/src/haiku/iuphaiku_focus.cpp b/src/haiku/iuphaiku_focus.cpp
new file mode 100644
index 0000000..bdce784
--- /dev/null
+++ b/src/haiku/iuphaiku_focus.cpp
@@ -0,0 +1,28 @@
+/** \file
+ * \brief Haiku Focus
+ *
+ * See Copyright Notice in "iup.h"
+ */
+
+#include <View.h>
+
+#include "iup.h"
+
+#include "iup_object.h"
+#include "iup_focus.h"
+#include "iup_attrib.h"
+#include "iup_drv.h"
+#include "iup_assert.h" 
+#include "iup_drv.h" 
+
+#include "iuphaiku_drv.h"
+
+
+void iupdrvSetFocus(Ihandle *ih)
+{
+  BView* view = (BView*)ih->handle;
+  view->LockLooper();
+  view->MakeFocus(true);
+  view->UnlockLooper();
+}
+
diff --git a/src/haiku/iuphaiku_font.cpp b/src/haiku/iuphaiku_font.cpp
new file mode 100644
index 0000000..2ece646
--- /dev/null
+++ b/src/haiku/iuphaiku_font.cpp
@@ -0,0 +1,277 @@
+/** \file
+ * \brief GTK Font mapping
+ *
+ * See Copyright Notice in "iup.h"
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <Font.h>
+#include <View.h>
+
+#include "iup.h"
+
+#include "iup_str.h"
+#include "iup_attrib.h"
+#include "iup_array.h"
+#include "iup_object.h"
+#include "iup_drv.h"
+#include "iup_drvfont.h"
+#include "iup_assert.h"
+
+#include "iuphaiku_drv.h"
+
+#define UNIMPLEMENTED printf("%s (%s %d) UNIMPLEMENTED\n",__func__,__FILE__,__LINE__);
+
+static const int fontHandleSize = B_FONT_FAMILY_LENGTH + B_FONT_STYLE_LENGTH + 7;
+
+typedef struct _IbeFont
+{
+	char standardfont[fontHandleSize];
+	BFont* font;
+} IbeFont;
+
+static Iarray* be_fonts = NULL;
+
+char* iupdrvGetSystemFont(void)
+{
+  static char str[B_FONT_FAMILY_LENGTH + B_FONT_STYLE_LENGTH + 7];
+  /* must return a static string, because it will be used as the default value
+   * for the FONT attribute */
+
+  font_family family;
+  font_style style;
+  be_plain_font->GetFamilyAndStyle(&family, &style);
+  float size = be_plain_font->Size();
+
+  // FIXME use one of IUP standard formats here (ParseWin, ParseX or ParsePango)
+  sprintf(str, "%s, %s %d",family, style, (int)size);
+  return str;
+}
+
+char* iupgtkGetPangoFontDescAttrib(Ihandle *ih)
+{
+	UNIMPLEMENTED
+		return NULL;
+}
+
+char* iupgtkGetPangoLayoutAttrib(Ihandle *ih)
+{
+	UNIMPLEMENTED
+		return NULL;
+}
+
+char* iupgtkGetFontIdAttrib(Ihandle *ih)
+{
+  /* Used by IupGLCanvas for IupGLUseFont */
+	UNIMPLEMENTED
+		return NULL;
+}
+
+static BFont* beFindFont(const char* standardfont)
+{
+  IbeFont* fonts = (IbeFont*)iupArrayGetData(be_fonts);
+  int count = iupArrayCount(be_fonts);
+
+  /* Check if the standardfont already exists in cache */
+  int i;
+  for (i = 0; i < count; i++)
+  {
+    if (iupStrEqualNoCase(standardfont, fonts[i].standardfont))
+      return fonts[i].font;
+  }
+
+  BFont* font = new BFont();
+  /* not found, create a new one */
+  {
+    int size = 0;
+    int is_bold = 0,
+      is_underline = 0,
+      is_strikeout = 0,
+      is_italic = 0;
+    char typeface[1024];
+    const char* mapped_name;
+
+    /* parse the old Windows format first */
+    if (!iupFontParseWin(standardfont, typeface, &size, &is_bold, &is_italic, &is_underline, &is_strikeout))
+    {
+      if (!iupFontParseX(standardfont, typeface, &size, &is_bold, &is_italic, &is_underline, &is_strikeout))
+      {
+        if (!iupFontParsePango(standardfont, typeface, &size, &is_bold, &is_italic, &is_underline, &is_strikeout))
+          return NULL;
+      }
+    }
+
+    /* Map standard names to native names */
+    mapped_name = iupFontGetPangoName(typeface);
+    if (mapped_name)
+    {
+      strcpy(typeface, mapped_name);
+    }
+
+	font->SetSize(size);
+	font->SetFamilyAndStyle(typeface, NULL);
+	uint16 face = 0;
+	if (is_bold) face |= B_BOLD_FACE;
+	if (is_italic) face |= B_ITALIC_FACE;
+	if (is_underline) face |= B_UNDERSCORE_FACE;
+	if (is_strikeout) face |= B_STRIKEOUT_FACE;
+	font->SetFace(face);
+  }
+
+  if (!font) 
+    return NULL;
+
+  /* create room in the array */
+  fonts = (IbeFont*)iupArrayInc(be_fonts);
+
+  strcpy(fonts[i].standardfont, standardfont);
+  fonts[i].font = font;
+  return fonts[i].font;
+}
+
+static BFont* beFontCreateNativeFont(Ihandle* ih, const char* value)
+{
+  BFont* bfont = beFindFont(value);
+  if (!bfont)
+  {
+    iupERROR1("Failed to create Font: %s", value); 
+    return NULL;
+  }
+
+  iupAttribSetStr(ih, "_IUP_HAIKUFONT", (char*)bfont);
+  return bfont;
+}
+
+
+int iupdrvSetStandardFontAttrib(Ihandle* ih, const char* value)
+{
+  BFont* bfont = beFontCreateNativeFont(ih, value);
+  if(!bfont)
+    return 1;
+
+  /* If FONT is changed, must update the SIZE attribute */
+  iupBaseUpdateSizeFromFont(ih);
+
+  /* FONT attribute must be able to be set before mapping, 
+    so the font is enable for size calculation. */
+  if (ih->handle && (ih->iclass->nativetype != IUP_TYPEVOID))
+  {
+	BHandler* handler = (BHandler*)ih->handle;
+	BView* view = viewFromHandler(handler);
+	if (!view) {
+		debugger("Invalid handle ! what is it ?");
+	}
+	view->SetFont(bfont);
+    //iupgtkFontUpdatePangoLayout(ih, gtkFontGetWidgetPangoLayout(ih));
+  }
+
+  return 1;
+}
+
+static int beFontHeight(const BFont* font)
+{
+  font_height height;
+  font->GetHeight(&height);
+  return (int)(height.ascent + height.descent + height.leading);
+}
+
+static BFont* beFontGet(Ihandle *ih)
+{
+  BFont* bfont = (BFont*)iupAttribGet(ih, "_IUP_HAIKUFONT");
+  if(!bfont)
+    bfont = beFontCreateNativeFont(ih, iupGetFontAttrib(ih));
+  return bfont;
+}
+
+void iupdrvFontGetMultiLineStringSize(Ihandle* ih, const char* str, int *w, int *h)
+{
+  int max_w = 0;
+
+  BFont* bfont = beFontGet(ih);
+  if (!bfont)
+  {
+    if (w) *w = 0;
+    if (h) *h = 0;
+    return;
+  }
+
+  int height = beFontHeight(bfont);
+
+  if (!str)
+  {
+    if (w) *w = 0;
+    if (h) *h = height;
+    return;
+  }
+  
+  if (str[0])
+  {
+    int len, lw;
+    const char *nextstr;
+    const char *curstr = str;
+
+    do
+    {
+      nextstr = iupStrNextLine(curstr, &len);
+      if (len)
+      {
+        lw = (int)bfont->StringWidth(curstr, len);
+        max_w = iupMAX(max_w, lw);
+      }
+
+      curstr = nextstr;
+    } while(*nextstr);
+  }
+
+  if (w) *w = max_w;
+  if (h) *h = height * iupStrLineCount(str);
+}
+
+int iupdrvFontGetStringWidth(Ihandle* ih, const char* str)
+{
+  BFont* bfont = beFontGet(ih);
+  if (!bfont || !str)
+  {
+	return 0;
+  }
+
+  return (int)bfont->StringWidth(str);
+}
+
+void iupdrvFontGetCharSize(Ihandle* ih, int *charwidth, int *charheight)
+{
+  BFont* befont = beFontGet(ih);
+  if(!befont)
+  {
+    if (charwidth)  *charwidth = 0;
+    if (charheight) *charheight = 0;
+    return;
+  }
+
+  if (charheight) {
+    *charheight = beFontHeight(befont);
+  }
+
+  if (charwidth) {
+    *charwidth = (int)befont->StringWidth("M");
+  }
+}
+
+void iupdrvFontInit(void)
+{
+  be_fonts = iupArrayCreate(50, sizeof(IbeFont));
+}
+
+void iupdrvFontFinish(void)
+{
+  int i, count = iupArrayCount(be_fonts);
+  IbeFont* fonts = (IbeFont*)iupArrayGetData(be_fonts);
+  for (i = 0; i < count; i++)
+  {
+    delete fonts[i].font;
+  }
+  iupArrayDestroy(be_fonts);
+}
diff --git a/src/haiku/iuphaiku_fontdlg.c b/src/haiku/iuphaiku_fontdlg.c
new file mode 100644
index 0000000..beb7778
--- /dev/null
+++ b/src/haiku/iuphaiku_fontdlg.c
@@ -0,0 +1,35 @@
+/** \file
+ * \brief IupFontDlg pre-defined dialog
+ *
+ * See Copyright Notice in "iup.h"
+ */
+
+#define UNIMPLEMENTED printf("%s (%s %d) UNIMPLEMENTED\n",__func__,__FILE__,__LINE__);
+#include <stdio.h>
+
+#include <string.h>
+#include <memory.h>
+
+#include "iup.h"
+
+#include "iup_object.h"
+#include "iup_attrib.h"
+#include "iup_str.h"
+#include "iup_dialog.h"
+
+#include "iuphaiku_drv.h"
+
+
+static int gtkFontDlgPopup(Ihandle* ih, int x, int y)
+{
+	UNIMPLEMENTED
+  return IUP_NOERROR;
+}
+
+void iupdrvFontDlgInitClass(Iclass* ic)
+{
+  ic->DlgPopup = gtkFontDlgPopup;
+
+  /* IupFontDialog GTK Only */
+  iupClassRegisterAttribute(ic, "PREVIEWTEXT", NULL, NULL, NULL, NULL, IUPAF_NO_INHERIT);
+}
diff --git a/src/haiku/iuphaiku_frame.cpp b/src/haiku/iuphaiku_frame.cpp
new file mode 100644
index 0000000..6b271e4
--- /dev/null
+++ b/src/haiku/iuphaiku_frame.cpp
@@ -0,0 +1,141 @@
+/** \file
+ * \brief Frame Control
+ *
+ * See Copyright Notice in "iup.h"
+ */
+
+#define UNIMPLEMENTED printf("%s (%s %d) UNIMPLEMENTED\n",__func__,__FILE__,__LINE__);
+
+#include <Box.h>
+#include <Rect.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <memory.h>
+#include <stdarg.h>
+
+#include "iup.h"
+
+#include "iup_object.h"
+#include "iup_layout.h"
+#include "iup_attrib.h"
+#include "iup_str.h"
+#include "iup_dialog.h"
+#include "iup_drv.h"
+#include "iup_drvfont.h"
+#include "iup_stdcontrols.h"
+
+#include "iuphaiku_drv.h"
+
+
+extern "C" {
+void iupdrvFrameGetDecorOffset(int *x, int *y)
+{
+  *x = 3;
+  *y = 1;
+}
+
+int iupdrvFrameHasClientOffset(void)
+{
+  return 1;
+}
+}
+
+static char* beFrameGetTitleAttrib(Ihandle* ih)
+{
+	UNIMPLEMENTED
+		return NULL;
+}
+
+static int beFrameSetTitleAttrib(Ihandle* ih, const char* value)
+{
+  if (iupAttribGetStr(ih, "_IUPFRAME_HAS_TITLE"))
+  {
+	BBox* box = (BBox*)ih->handle;
+	box->SetLabel(value);
+  }
+  return 0;
+}
+
+static int gtkFrameSetBgColorAttrib(Ihandle* ih, const char* value)
+{
+	UNIMPLEMENTED
+  return 1;
+}
+
+static int gtkFrameSetFgColorAttrib(Ihandle* ih, const char* value)
+{
+	UNIMPLEMENTED
+  return 1;
+}
+
+/*
+static int beFrameSetStandardFontAttrib(Ihandle* ih, const char* value)
+{
+  iupdrvSetStandardFontAttrib(ih, value);
+
+  if (ih->handle)
+  {
+    
+  }
+  return 1;
+}
+
+static void* beFrameGetInnerNativeContainerHandleMethod(Ihandle* ih, Ihandle* child)
+{
+  return ih->handle;
+}
+*/
+
+static int beFrameMapMethod(Ihandle* ih)
+{
+  char *value, *title = iupAttribGet(ih, "TITLE");
+  BBox* bbox = new BBox(BRect(0, 0, 10, 10), title);
+  ih->handle = (InativeHandle*)bbox;
+  new BBox(BRect(0, 0, 10, 10), title);
+
+  if(!ih->handle)
+	return IUP_ERROR;
+
+  title = iupAttribGet(ih, "TITLE");
+
+  if (title)
+    iupAttribSetStr(ih, "_IUPFRAME_HAS_TITLE", "1");
+  else
+  {
+    value = iupAttribGetStr(ih, "SUNKEN");
+    if (iupStrBoolean(value))
+	  bbox->SetBorder(B_FANCY_BORDER);
+    else
+	  bbox->SetBorder(B_PLAIN_BORDER);
+
+    if (iupAttribGet(ih, "BGCOLOR"))
+      iupAttribSetStr(ih, "_IUPFRAME_HAS_BGCOLOR", "1");
+  }
+
+  iuphaikuBaseAddToParent(ih);
+
+  return IUP_NOERROR;
+}
+
+extern "C" {
+void iupdrvFrameInitClass(Iclass* ic)
+{
+  /* Driver Dependent Class functions */
+  ic->Map = beFrameMapMethod;
+//  ic->GetInnerNativeContainerHandle = beFrameGetInnerNativeContainerHandleMethod;
+
+  /* Driver Dependent Attribute functions */
+
+  /* Overwrite Common */
+  //iupClassRegisterAttribute(ic, "STANDARDFONT", NULL, beFrameSetStandardFontAttrib, IUPAF_SAMEASSYSTEM, "DEFAULTFONT", IUPAF_NO_SAVE|IUPAF_NOT_MAPPED);
+
+  /* Visual */
+  iupClassRegisterAttribute(ic, "BGCOLOR", NULL, gtkFrameSetBgColorAttrib, IUPAF_SAMEASSYSTEM, "DLGBGCOLOR", IUPAF_DEFAULT);
+
+  /* Special */
+  iupClassRegisterAttribute(ic, "FGCOLOR", NULL, gtkFrameSetFgColorAttrib, IUPAF_SAMEASSYSTEM, "DLGFGCOLOR", IUPAF_DEFAULT);
+  iupClassRegisterAttribute(ic, "TITLE", beFrameGetTitleAttrib, beFrameSetTitleAttrib, NULL, NULL, IUPAF_NO_DEFAULTVALUE|IUPAF_NO_INHERIT);
+}
+}
diff --git a/src/haiku/iuphaiku_globalattrib.c b/src/haiku/iuphaiku_globalattrib.c
new file mode 100644
index 0000000..61dc0a5
--- /dev/null
+++ b/src/haiku/iuphaiku_globalattrib.c
@@ -0,0 +1,55 @@
+/** \file
+ * \brief GTK Driver iupdrvSetGlobal
+ *
+ * See Copyright Notice in "iup.h"
+ */
+
+#include <stdio.h>
+#include <string.h>
+
+#include "iup.h"
+#include "iupcbs.h"
+
+#include "iup_object.h"
+#include "iup_str.h"
+#include "iup_drv.h"
+#include "iup_drvinfo.h"
+#include "iup_key.h"
+
+#include "iuphaiku_drv.h"
+
+
+int iupgtk_utf8autoconvert = 1;
+int iupgtk_globalmenu = 0;
+
+#define UNIMPLEMENTED printf("%s (%s %d) UNIMPLEMENTED\n",__func__,__FILE__,__LINE__);
+
+int iupdrvSetGlobal(const char *name, const char *value)
+{
+  if (iupStrEqual(name, "INPUTCALLBACKS"))
+  {
+	UNIMPLEMENTED
+	return 1; // Return 0 when we handle it properly !
+  }
+  if (iupStrEqual(name, "SINGLEINSTANCE"))
+  {
+	UNIMPLEMENTED
+	return 1; // Return 0 when we handle it properly !
+  }
+
+  // Other attributes are ignored by the driver. They are forwarded to the main
+  // implementation of IUP.
+  return 1;
+}
+
+int iupdrvCheckMainScreen(int *w, int *h)
+{
+	UNIMPLEMENTED
+  return 0;
+}
+
+char *iupdrvGetGlobal(const char *name)
+{
+  // TODO we can return some platform-specific info here
+  return NULL;
+}
diff --git a/src/haiku/iuphaiku_help.c b/src/haiku/iuphaiku_help.c
new file mode 100644
index 0000000..e2ef8ba
--- /dev/null
+++ b/src/haiku/iuphaiku_help.c
@@ -0,0 +1,23 @@
+/** \file
+ * \brief GTK Driver IupHelp for non Windows systems
+ *
+ * See Copyright Notice in "iup.h"
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "iup.h"
+
+#include "iup_str.h"
+
+#define UNIMPLEMENTED printf("%s (%s %d) UNIMPLEMENTED\n",__func__,__FILE__,__LINE__);
+
+int IupHelp(const char *url)
+{
+  // TODO open the html page in web browser
+  UNIMPLEMENTED
+
+  return -1;
+}
diff --git a/src/haiku/iuphaiku_image.cpp b/src/haiku/iuphaiku_image.cpp
new file mode 100644
index 0000000..09a7679
--- /dev/null
+++ b/src/haiku/iuphaiku_image.cpp
@@ -0,0 +1,160 @@
+/** \file
+ * \brief Image Resource.
+ *
+ * See Copyright Notice in "iup.h"
+ */
+
+#include <Bitmap.h>
+#include <GraphicsDefs.h>
+#include <Screen.h>
+#include <TranslationUtils.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <memory.h>
+
+#include "iup.h"
+
+#include "iup_object.h"
+#include "iup_attrib.h"
+#include "iup_str.h"
+#include "iup_image.h"
+#include "iup_drvinfo.h"
+
+#include "iuphaiku_drv.h"
+
+#define UNIMPLEMENTED printf("%s (%s %d) UNIMPLEMENTED\n",__func__,__FILE__,__LINE__);
+
+void iupdrvImageGetRawData(void* handle, unsigned char* imgdata)
+{
+	UNIMPLEMENTED
+}
+
+void* iupdrvImageCreateImageRaw(int width, int height, int bpp, iupColor* colors, int colors_count, unsigned char *imgdata)
+{
+	UNIMPLEMENTED
+		return NULL;
+}
+
+void* iupdrvImageCreateImage(Ihandle *ih, const char* bgcolor, int make_inactive)
+{
+  int bpp = iupAttribGetInt(ih, "BPP");
+  color_space space;
+  if (bpp == 8)
+    space = B_CMAP8;
+  else if (bpp == 32)
+	space = B_RGBA32;
+  else if(bpp == 24)
+	space = B_RGB24;
+  else
+	UNIMPLEMENTED
+  BBitmap* bitmap = new BBitmap(BRect(0, 0, ih->currentwidth - 1, ih->currentheight - 1), space);
+
+
+  unsigned char* imgdata = (unsigned char*)iupAttribGetStr(ih, "WID");
+
+  if (make_inactive)
+  {
+    unsigned char bg_r = 0, bg_g = 0, bg_b = 0;
+    iupStrToRGB(bgcolor, &bg_r, &bg_g, &bg_b);
+
+	if (bpp >= 24)
+    for (int y=0; y<ih->currentheight; y++)
+    for (int x=0; x<ih->currentwidth; x++)
+	{
+      rgb_color* c = (rgb_color*)(imgdata + (x + y * ih->currentwidth) * bpp / 8);
+	  if (bpp == 32) {
+	    c->red = iupALPHABLEND(c->red, bg_r, c->alpha);
+	    c->green = iupALPHABLEND(c->green, bg_r, c->alpha);
+	    c->blue = iupALPHABLEND(c->blue, bg_r, c->alpha);
+	  }
+	  iupImageColorMakeInactive(&c->red, &c->blue, &c->green, bg_r, bg_g, bg_b);
+	} else if(bpp == 8) {
+	  // FIXME this isn't working too well...
+	  rgb_color disable = make_color(bg_r, bg_g, bg_b);
+	  unsigned char cid = BScreen().IndexForColor(disable);
+      for (int y=0; y<ih->currentheight; y++)
+      for (int x=y&1; x<ih->currentwidth; x+=2) {
+        *(imgdata + x + y * ih->currentwidth) = cid;
+	  }
+	} else
+	  UNIMPLEMENTED // Not sure how to do that for 16 bit pics ?
+	
+  }
+
+  bitmap->SetBits(imgdata, ih->currentwidth * ih->currentheight * bpp / 8, 0, space);
+	  
+  return bitmap;
+}
+
+void* iupdrvImageCreateIcon(Ihandle *ih)
+{
+  return iupdrvImageCreateImage(ih, NULL, 0);
+}
+
+void* iupdrvImageCreateCursor(Ihandle *ih)
+{
+	UNIMPLEMENTED
+		return NULL;
+}
+
+void* iupdrvImageCreateMask(Ihandle *ih)
+{
+	UNIMPLEMENTED
+		return NULL;
+}
+
+void* iupdrvImageLoad(const char* name, int type)
+{
+	if(type == IUPIMAGE_CURSOR) {
+		UNIMPLEMENTED
+	} else {
+		// TODO the GTK driver attempts to load icons and cursors from the GTK theme
+		// Try using the translation kit
+		/*
+		BBitmap* bitmap = BTranslationUtils::GetBitmap(name);
+		if (bitmap == NULL)
+		{
+			// likely an image from iupimglib ?
+			printf("Loading image %s\n", name);
+			UNIMPLEMENTED
+		}
+		return bitmap;
+		*/
+
+		// TODO try loading from resources ?
+		// UNIMPLEMENTED
+	}
+
+	return NULL;
+}
+
+int iupdrvImageGetInfo(void* handle, int *w, int *h, int *bpp)
+{
+  BBitmap* bmp = (BBitmap*)handle;
+  BRect r = bmp->Bounds();
+
+  if(w) *w = r.Width();
+  if(h) *h = r.Height();
+  if(bpp) {
+	switch(bmp->ColorSpace()) {
+	  case B_RGB32: *bpp=32; break;
+	  case B_CMAP8: *bpp=8; break;
+	  default: UNIMPLEMENTED
+	}
+  }
+  return 1;
+}
+
+int iupdrvImageGetRawInfo(void* handle, int *w, int *h, int *bpp, iupColor* colors, int *colors_count)
+{
+  /* GdkPixbuf are only 24 bpp or 32 bpp */
+  (void)colors;
+  (void)colors_count;
+  return iupdrvImageGetInfo(handle, w, h, bpp);
+}
+
+void iupdrvImageDestroy(void* handle, int type)
+{
+	UNIMPLEMENTED
+}
diff --git a/src/haiku/iuphaiku_info.cpp b/src/haiku/iuphaiku_info.cpp
new file mode 100644
index 0000000..7061362
--- /dev/null
+++ b/src/haiku/iuphaiku_info.cpp
@@ -0,0 +1,190 @@
+/** \file
+ * \brief MAC OS System Information
+ *
+ * See Copyright Notice in "iup.h"
+ */
+
+#include <stdio.h>
+#include <stdlib.h> 
+#include <string.h>
+
+#include <Entry.h>
+#include <OS.h>
+#include <Screen.h>
+
+/* This module should depend only on IUP core headers */
+
+#include <sys/utsname.h>
+#include <unistd.h>
+#include <limits.h>
+#include <errno.h>
+#include <sys/stat.h>
+#include <langinfo.h>
+
+#include "iup.h" 
+
+#include "iup_str.h"
+#include "iup_drv.h"
+#include "iup_drvinfo.h"
+
+#define IUP_MAC_ERROR -1
+#define UNIMPLEMENTED printf("%s (%s %d) UNIMPLEMENTED\n",__func__,__FILE__,__LINE__);
+
+int iupdrvMakeDirectory(const char* name) 
+{
+  mode_t oldmask = umask((mode_t)0);
+  int fail =  mkdir(name, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP |
+                          S_IWGRP | S_IXGRP | S_IROTH | S_IXOTH);
+  umask (oldmask);
+  if (fail)
+    return 0;
+  return 1;
+}
+
+int iupdrvIsFile(const char* name)
+{
+  return BEntry(name).IsFile();
+}
+
+int iupdrvIsDirectory(const char* name)
+{
+  return BEntry(name).IsDirectory();
+}            
+
+char* iupdrvGetCurrentDirectory(void)
+{
+  size_t size = 256;
+  char *buffer = (char *)malloc(size);
+
+  for (;;)
+  {
+    if (getcwd(buffer, size) != NULL)
+      return buffer;
+
+    if (errno != ERANGE)
+    {
+      free(buffer);
+      return NULL;
+    }
+
+    size += size;
+    buffer = (char *)realloc(buffer, size);
+  }
+
+  return NULL;
+}
+
+int iupdrvSetCurrentDirectory(const char* dir)
+{
+  return chdir(dir) == 0? 1: 0;
+}
+
+int iupdrvGetWindowDecor(void* wnd, int *border, int *caption)
+{
+	UNIMPLEMENTED
+
+  *border  = 0;
+  *caption = 0;
+
+  return 0;
+}
+
+void iupdrvGetScreenSize(int *width, int *height)
+{
+	BScreen screen;
+	BRect frame = screen.Frame();
+
+	if(width) *width = (int)frame.right + 1;
+	if(height) *height = (int)frame.bottom + 1;
+}
+
+void iupdrvGetFullSize(int *width, int *height)
+{
+	// TODO is this only useful in mutli-monitor situations ?
+	iupdrvGetScreenSize(width, height);
+}
+
+int iupdrvGetScreenDepth(void)
+{
+	BScreen screen;
+
+	switch(screen.ColorSpace())
+	{
+		case B_CMAP8: return 8;
+		case B_RGB15: return 15;
+		case B_RGB32: return 32;
+		default:
+			printf("%s (%s:%d) FIXME unknown colorspace\n", __func__, __FILE__, __LINE__);
+			return 0;
+	}
+}
+
+float iupdrvGetScreenDpi(void)
+{
+	UNIMPLEMENTED
+		return 0;
+}
+
+void iupdrvGetCursorPos(int *x, int *y)
+{
+	UNIMPLEMENTED
+}
+
+void iupdrvGetKeyState(char* key)
+{
+	UNIMPLEMENTED
+}
+
+char* iupdrvLocaleInfo(void)
+{
+  return iupStrGetMemoryCopy(nl_langinfo(CODESET));
+}
+
+/* Everything below is copypasted from mot/iupunix.c, but that one depends on X11 :( */
+char *iupdrvGetSystemName(void)
+{
+  struct utsname un;
+  char *str = iupStrGetMemory(50); 
+
+  uname(&un);
+  if (iupStrEqualNoCase(un.sysname, "Darwin"))
+    strcpy(str, "MacOS");
+  else
+    strcpy(str, un.sysname);
+
+  return str;
+}
+
+char *iupdrvGetSystemVersion(void)
+{
+  struct utsname un;
+  char *str = iupStrGetMemory(100); 
+
+  uname(&un);
+  if (iupStrEqualNoCase(un.sysname, "Darwin"))
+  {
+    int release = atoi(un.release);
+    sprintf(str, "%d", release-4);
+  }
+  else
+  {
+    strcpy(str, un.release);
+    strcat(str, ".");
+    strcat(str, un.version);
+  }
+
+  return str;
+}
+
+char *iupdrvGetComputerName(void)
+{
+  char* str = iupStrGetMemory(50);
+  gethostname(str, 50);
+  return str;
+}
+
+char *iupdrvGetUserName(void)
+{
+  return (char*)getlogin();
+}
+
diff --git a/src/haiku/iuphaiku_label.cpp b/src/haiku/iuphaiku_label.cpp
new file mode 100644
index 0000000..a0042b8
--- /dev/null
+++ b/src/haiku/iuphaiku_label.cpp
@@ -0,0 +1,288 @@
+/** \file
+ * \brief Label Control
+ *
+ * See Copyright Notice in "iup.h"
+ */
+
+#include <StringView.h>
+#include <View.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <memory.h>
+#include <stdarg.h>
+
+#include "iup.h"
+#include "iupcbs.h"
+
+#include "iup_object.h"
+#include "iup_layout.h"
+#include "iup_attrib.h"
+#include "iup_str.h"
+#include "iup_image.h"
+#include "iup_label.h"
+#include "iup_drv.h"
+#include "iup_image.h"
+#include "iup_focus.h"
+
+#include "iuphaiku_drv.h"
+
+#define UNIMPLEMENTED printf("%s (%s %d) UNIMPLEMENTED\n",__func__,__FILE__,__LINE__);
+
+static int beLabelSetTitleAttrib(Ihandle* ih, const char* value)
+{
+  if (ih->data->type == IUP_LABEL_TEXT) {
+    BStringView* stringView = (BStringView*)ih->handle;
+  	stringView->SetText(iuphaikuStrConvertToUTF8(value));
+
+	// TODO handle the mnemonic ?
+
+	return 1;
+  }
+  return 0;
+}
+
+static int gtkLabelSetWordWrapAttrib(Ihandle* ih, const char* value)
+{
+	UNIMPLEMENTED
+  return 0;
+}
+
+static int gtkLabelSetEllipsisAttrib(Ihandle* ih, const char* value)
+{
+	UNIMPLEMENTED
+  return 0;
+}
+
+static int gtkLabelSetAlignmentAttrib(Ihandle* ih, const char* value)
+{
+  if (ih->data->type != IUP_LABEL_SEP_HORIZ && ih->data->type != IUP_LABEL_SEP_VERT)
+  {
+    BStringView* view = (BStringView*)ih->handle;
+    char value1[30]="", value2[30]="";
+
+    iupStrToStrStr(value, value1, value2, ':');
+    if (iupStrEqualNoCase(value1, "ARIGHT"))
+		view->SetAlignment(B_ALIGN_RIGHT);
+    else if (iupStrEqualNoCase(value1, "ACENTER"))
+		view->SetAlignment(B_ALIGN_CENTER);
+    else /* "ALEFT" */
+		view->SetAlignment(B_ALIGN_LEFT);
+
+	/* TODO
+    if (iupStrEqualNoCase(value2, "ABOTTOM"))
+    else if (iupStrEqualNoCase(value2, "ATOP"))
+    else  // ACENTER (default)
+	*/
+
+	return 1;
+  } else {
+    // TODO handle image labels as well, but ignore separators
+	UNIMPLEMENTED
+    return 0;
+  }
+}
+
+static int gtkLabelSetPaddingAttrib(Ihandle* ih, const char* value)
+{
+  if (ih->handle && ih->data->type != IUP_LABEL_SEP_HORIZ && ih->data->type != IUP_LABEL_SEP_VERT)
+  {
+	// There's no way to do that in Haiku BStringView ?
+	UNIMPLEMENTED
+    return 0;
+  } else
+    return 1; /* store until not mapped, when mapped will be set again */
+}
+
+static char* gtkLabelGetWidgetPangoLayoutAttrib(Ihandle* ih)
+{
+	UNIMPLEMENTED
+    return NULL;
+}
+
+
+static void beLabelSetPixbuf(Ihandle* ih, const char* name, int make_inactive)
+{
+  BView* widget = (BView*)ih->handle;
+
+  if (name)
+  {
+    BBitmap* bitmap = (BBitmap*)iupImageGetImage(name, ih, make_inactive);
+	// TODO we may need to play with source and destination rects to align the
+	// image here ? Or maybe it's simpler to handle that at view level...
+	widget->SetViewBitmap(bitmap, B_FOLLOW_NONE, 0);
+  } else {
+	widget->ClearViewBitmap();
+  }
+}
+
+static int gtkLabelSetImageAttrib(Ihandle* ih, const char* value)
+{
+  if (ih->data->type == IUP_LABEL_IMAGE)
+  {
+    if (iupdrvIsActive(ih))
+      beLabelSetPixbuf(ih, value, 0);
+    else
+    {
+      if (!iupAttribGet(ih, "IMINACTIVE"))
+      {
+        /* if not active and IMINACTIVE is not defined 
+           then automaticaly create one based on IMAGE */
+        beLabelSetPixbuf(ih, value, 1); /* make_inactive */
+      }
+    }
+    return 1;
+  }
+  else
+    return 0;
+}
+
+static int gtkLabelSetImInactiveAttrib(Ihandle* ih, const char* value)
+{
+  if (ih->data->type == IUP_LABEL_IMAGE)
+  {
+    if (!iupdrvIsActive(ih))
+    {
+      if (value)
+        beLabelSetPixbuf(ih, value, 0);
+      else
+      {
+        /* if not defined then automaticaly create one based on IMAGE */
+        char* name = iupAttribGet(ih, "IMAGE");
+        beLabelSetPixbuf(ih, name, 1); /* make_inactive */
+      }
+    }
+    return 1;
+  }
+  else
+    return 0;
+}
+
+static int gtkLabelSetActiveAttrib(Ihandle* ih, const char* value)
+{
+  /* update the inactive image if necessary */
+  if (ih->data->type == IUP_LABEL_IMAGE)
+  {
+    if (!iupStrBoolean(value))
+    {
+      char* name = iupAttribGet(ih, "IMINACTIVE");
+      if (name)
+        beLabelSetPixbuf(ih, name, 0);
+      else
+      {
+        /* if not defined then automaticaly create one based on IMAGE */
+        name = iupAttribGet(ih, "IMAGE");
+        beLabelSetPixbuf(ih, name, 1); /* make_inactive */
+      }
+    }
+    else
+    {
+      /* must restore the normal image */
+      char* name = iupAttribGet(ih, "IMAGE");
+      beLabelSetPixbuf(ih, name, 0);
+    }
+  }
+
+  return iupBaseSetActiveAttrib(ih, value);
+}
+
+class IUPSeparator: public BView
+{
+  public:
+	IUPSeparator(/*orientation dir*/)
+	  : BView(BRect(0,0,1,1), "Separator", B_FOLLOW_NONE, B_WILL_DRAW)
+	{
+	  SetHighColor(tint_color(ui_color(B_PANEL_BACKGROUND_COLOR),
+	    B_DISABLED_LABEL_TINT));
+
+	}
+
+	void Draw(BRect updateRect)
+	{
+      BRect bounds = Bounds();
+	  if (bounds.Width() > bounds.Height())
+	  {
+	    StrokeLine(bounds.LeftTop(), bounds.RightTop());
+	  } else {
+	    StrokeLine(bounds.LeftTop(), bounds.LeftBottom());
+	  }
+	}
+};
+
+static int beLabelMapMethod(Ihandle* ih)
+{
+  char* value = iupAttribGet(ih, "SEPARATOR");
+  BView* label = NULL;
+  
+  if (value)
+  {
+	// TODO maybe we need to hint the separator direction here ?
+	label = new IUPSeparator();
+    if (iupStrEqualNoCase(value, "HORIZONTAL"))
+    {
+      ih->data->type = IUP_LABEL_SEP_HORIZ;
+	} else {
+      ih->data->type = IUP_LABEL_SEP_VERT;
+	}
+  } else {
+    value = iupAttribGet(ih, "IMAGE");
+    if (value)
+	{
+      ih->data->type = IUP_LABEL_IMAGE;
+	  // FIXME We rely on SetViewBitmap to put the image on screen. But this
+	  // doesn't work too well when the image needs an alpha channel
+	  label = new BView(BRect(0,0,10,10),"Label/Image", B_FOLLOW_NONE, 0);
+	} else {
+      ih->data->type = IUP_LABEL_TEXT;
+	  label = new BStringView(BRect(0, 0, 10, 10),"StringView", "");
+	}
+  }
+
+  if (!label)
+    return IUP_ERROR;
+
+  label->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
+
+  ih->handle = (InativeHandle*)label;
+
+  iuphaikuBaseAddToParent(ih);
+
+  return IUP_NOERROR;
+}
+
+void iupdrvLabelInitClass(Iclass* ic)
+{
+  /* Driver Dependent Class functions */
+  ic->Map = beLabelMapMethod;
+
+  /* Driver Dependent Attribute functions */
+
+  /* Common GTK only (when text is in a secondary element) */
+  iupClassRegisterAttribute(ic, "WIDGETPANGOLAYOUT", gtkLabelGetWidgetPangoLayoutAttrib, NULL, NULL, NULL, IUPAF_NO_INHERIT);
+
+  /* Overwrite Visual */
+  iupClassRegisterAttribute(ic, "ACTIVE", iupBaseGetActiveAttrib, gtkLabelSetActiveAttrib, IUPAF_SAMEASSYSTEM, "YES", IUPAF_DEFAULT);
+
+  /* Visual */
+  iupClassRegisterAttribute(ic, "BGCOLOR", iupBaseNativeParentGetBgColorAttrib, NULL, IUPAF_SAMEASSYSTEM, "DLGBGCOLOR", IUPAF_DEFAULT);
+
+  /* Special */
+  iupClassRegisterAttribute(ic, "FGCOLOR", NULL, iupdrvBaseSetFgColorAttrib, IUPAF_SAMEASSYSTEM, "DLGFGCOLOR", IUPAF_DEFAULT);
+  iupClassRegisterAttribute(ic, "TITLE", NULL, beLabelSetTitleAttrib, NULL, NULL, IUPAF_NO_DEFAULTVALUE|IUPAF_NO_INHERIT);
+
+  /* IupLabel only */
+  iupClassRegisterAttribute(ic, "ALIGNMENT", NULL, gtkLabelSetAlignmentAttrib, "ALEFT:ACENTER", NULL, IUPAF_NO_INHERIT);  /* force new default value */
+  iupClassRegisterAttribute(ic, "IMAGE", NULL, gtkLabelSetImageAttrib, NULL, NULL, IUPAF_IHANDLENAME|IUPAF_NO_DEFAULTVALUE|IUPAF_NO_INHERIT);
+  iupClassRegisterAttribute(ic, "PADDING", iupLabelGetPaddingAttrib, gtkLabelSetPaddingAttrib, IUPAF_SAMEASSYSTEM, "0x0", IUPAF_NOT_MAPPED);
+
+  /* IupLabel GTK and Motif only */
+  iupClassRegisterAttribute(ic, "IMINACTIVE", NULL, gtkLabelSetImInactiveAttrib, NULL, NULL, IUPAF_IHANDLENAME|IUPAF_NO_DEFAULTVALUE|IUPAF_NO_INHERIT);
+
+  /* IupLabel Windows and GTK only */
+  iupClassRegisterAttribute(ic, "WORDWRAP", NULL, gtkLabelSetWordWrapAttrib, NULL, NULL, IUPAF_DEFAULT);
+  iupClassRegisterAttribute(ic, "ELLIPSIS", NULL, gtkLabelSetEllipsisAttrib, NULL, NULL, IUPAF_DEFAULT);
+
+  /* IupLabel GTK only */
+  iupClassRegisterAttribute(ic, "MARKUP", NULL, NULL, NULL, NULL, IUPAF_DEFAULT);
+}
diff --git a/src/haiku/iuphaiku_list.cpp b/src/haiku/iuphaiku_list.cpp
new file mode 100644
index 0000000..30b3bd2
--- /dev/null
+++ b/src/haiku/iuphaiku_list.cpp
@@ -0,0 +1,556 @@
+/** \file
+ * \brief List Control
+ *
+ * See Copyright Notice in "iup.h"
+ */
+
+#define UNIMPLEMENTED printf("%s (%s %d) UNIMPLEMENTED\n",__func__,__FILE__,__LINE__);
+
+#include <ListView.h>
+#include <MenuItem.h>
+#include <MenuField.h>
+#include <ScrollView.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <memory.h>
+#include <stdarg.h>
+
+#include "iup.h"
+#include "iupcbs.h"
+
+#include "iup_object.h"
+#include "iup_layout.h"
+#include "iup_attrib.h"
+#include "iup_str.h"
+#include "iup_drv.h"
+#include "iup_drvfont.h"
+#include "iup_mask.h"
+#include "iup_key.h"
+#include "iup_image.h"
+#include "iup_list.h"
+
+#include "iuphaiku_drv.h"
+
+
+enum
+{
+  IUPGTK_LIST_IMAGE,  /* "pixbuf" */
+  IUPGTK_LIST_TEXT,  /* "text" */
+  IUPGTK_LIST_LAST_DATA  /* used as a count */
+};
+
+void iupdrvListAddItemSpace(Ihandle* ih, int *h)
+{
+  (void)ih;
+  *h += 3;
+}
+
+void iupdrvListAddBorders(Ihandle* ih, int *x, int *y)
+{
+  int border_size = 2*5;
+  (*x) += border_size;
+  (*y) += border_size;
+
+  if (ih->data->is_dropdown)
+  {
+#ifdef HILDON
+    (*x) += 9; /* extra space for the dropdown button */
+#else
+    (*x) += 5; /* extra space for the dropdown button */
+#endif
+
+    if (ih->data->has_editbox)
+      (*x) += 5; /* another extra space for the dropdown button */
+    else
+    {
+      (*y) += 4; /* extra padding space */
+      (*x) += 4; /* extra padding space */
+    }
+  }
+  else
+  {
+    if (ih->data->has_editbox)
+      (*y) += 2*3; /* internal border between editbox and list */
+  }
+}
+
+int iupdrvListGetCount(Ihandle* ih)
+{
+  BListView* listview = (BListView*)ih->handle;
+  return listview->CountItems();
+}
+
+BListView* iuphaikuGetListView(BView* view)
+{
+  // TODO maybe it is easier to get ScrollBar->Target ?
+  BListView* listview = dynamic_cast<BListView*>(view);
+  if(!listview)
+  {
+	BView* previous = view;
+	previous->LockLooper();
+	view = view->ChildAt(0);
+	previous->UnlockLooper();
+	while(view && !listview)
+	{
+      listview = dynamic_cast<BListView*>(view);
+	  view = view->NextSibling();
+	}
+  }
+
+  return listview;
+}
+
+void iupdrvListAppendItem(Ihandle* ih, const char* value)
+{
+  BView* view = (BView*)ih->handle;
+
+  BMenuField* menu = dynamic_cast<BMenuField*>(view);
+  if(menu)
+  {
+    menu->Menu()->AddItem(new BMenuItem(value, NULL));
+	return;
+  }
+
+  BListView* listview = iuphaikuGetListView(view);
+
+  if(listview)
+  {
+    BListItem* item = new BStringItem(value);
+	listview->LockLooper();
+    listview->AddItem(item);
+	listview->UnlockLooper();
+  } else {
+    fprintf(stderr, "View hierarchy problem\n");
+  }
+
+}
+
+void iupdrvListInsertItem(Ihandle* ih, int pos, const char* value)
+{
+	UNIMPLEMENTED
+}
+
+void iupdrvListRemoveItem(Ihandle* ih, int pos)
+{
+  BView* view = (BView*)ih->handle;
+
+  BMenuField* menu = dynamic_cast<BMenuField*>(view);
+  if(menu)
+  {
+	UNIMPLEMENTED
+	return;
+  }
+  
+  BListView* listview = iuphaikuGetListView(view);
+  if(listview) {
+	BListItem* item = listview->RemoveItem(pos - 1);
+	delete item;
+  } else {
+    fprintf(stderr, "View hierarchy problem\n");
+  }
+}
+
+void iupdrvListRemoveAllItems(Ihandle* ih)
+{
+  BView* view = (BView*)ih->handle;
+
+  BMenuField* menu = dynamic_cast<BMenuField*>(view);
+  if(menu)
+  {
+	UNIMPLEMENTED
+	return;
+  }
+  
+  BListView* listview = iuphaikuGetListView(view);
+  if(listview) {
+	while(!listview->IsEmpty()) {
+	  BListItem* item = listview->RemoveItem(0L);
+	  delete item;
+	}
+  } else {
+    fprintf(stderr, "View hierarchy problem\n");
+  }
+}
+
+
+/*********************************************************************************/
+
+/*
+static int gtkListSetStandardFontAttrib(Ihandle* ih, const char* value)
+{
+	UNIMPLEMENTED
+  return 1;
+}
+*/
+
+static char* haikuListGetIdValueAttrib(Ihandle* ih, int id)
+{
+  BView* view = (BView*)ih->handle;
+
+  BMenuField* menu = dynamic_cast<BMenuField*>(view);
+  if(menu)
+  {
+	UNIMPLEMENTED
+	return NULL;
+  }
+
+  BListView* listview = iuphaikuGetListView(view);
+
+  if(listview)
+  {
+	BStringItem* item = (BStringItem*)listview->ItemAt(id - 1);
+	return (char*)item->Text();
+  } else {
+    fprintf(stderr, "View hierarchy problem\n");
+  }
+
+  return NULL;
+}
+
+
+static int gtkListSetBgColorAttrib(Ihandle* ih, const char* value)
+{
+	UNIMPLEMENTED
+		return 0;
+}
+
+static int gtkListSetFgColorAttrib(Ihandle* ih, const char* value)
+{
+	UNIMPLEMENTED
+  return 1;
+}
+
+static char* haikuListGetValueAttrib(Ihandle* ih)
+{
+  BView* view = (BView*)ih->handle;
+
+  BMenuField* menu = dynamic_cast<BMenuField*>(view);
+  if(menu)
+  {
+	UNIMPLEMENTED
+	return NULL;
+  }
+
+  BListView* listview = iuphaikuGetListView(view);
+
+  if(listview)
+  {
+	BStringItem* item = (BStringItem*)
+	  listview->ItemAt(listview->CurrentSelection());
+	fprintf(stderr, "IEMTXT %s", item->Text());
+	return (char*)item->Text();
+  } else {
+    fprintf(stderr, "View hierarchy problem\n");
+  }
+
+  return NULL;
+}
+
+static int gtkListSetValueAttrib(Ihandle* ih, const char* value)
+{
+  if (ih->data->has_editbox)
+	UNIMPLEMENTED
+
+  BView* view = (BView*)ih->handle;
+
+  BMenuField* menu = dynamic_cast<BMenuField*>(view);
+  if(menu)
+  {
+	int pos;
+    if (iupStrToInt(value, &pos)==1)
+	  menu->Menu()->ItemAt(pos - 1)->SetMarked(true);
+	else
+	  UNIMPLEMENTED
+	return 0;
+  }
+
+  BListView* listview = iuphaikuGetListView(view);
+
+  if(listview)
+  {
+    if (!ih->data->is_multiple) {
+	  int pos;
+      if (iupStrToInt(value, &pos)==1)
+	    listview->Select(pos - 1);
+	  else
+		listview->DeselectAll();
+	} else
+	  UNIMPLEMENTED
+	
+  } else {
+    fprintf(stderr, "View hierarchy problem\n");
+  }
+
+  return 0;
+}
+
+static int gtkListSetShowDropdownAttrib(Ihandle* ih, const char* value)
+{
+	UNIMPLEMENTED
+  return 0;
+}
+
+static int gtkListSetTopItemAttrib(Ihandle* ih, const char* value)
+{
+	UNIMPLEMENTED
+  return 0;
+}
+
+static int gtkListSetSpacingAttrib(Ihandle* ih, const char* value)
+{
+	UNIMPLEMENTED
+    return 1; /* store until not mapped, when mapped will be set again */
+}
+
+static int gtkListSetPaddingAttrib(Ihandle* ih, const char* value)
+{
+  UNIMPLEMENTED
+    return 1; /* store until not mapped, when mapped will be set again */
+}
+
+static int gtkListSetSelectionAttrib(Ihandle* ih, const char* value)
+{
+	UNIMPLEMENTED
+  return 0;
+}
+
+static char* gtkListGetSelectionAttrib(Ihandle* ih)
+{
+	UNIMPLEMENTED
+  return NULL;
+}
+
+static int gtkListSetSelectionPosAttrib(Ihandle* ih, const char* value)
+{
+	UNIMPLEMENTED
+  return 0;
+}
+
+static char* gtkListGetSelectionPosAttrib(Ihandle* ih)
+{
+	UNIMPLEMENTED
+  return NULL;
+}
+
+static int gtkListSetSelectedTextAttrib(Ihandle* ih, const char* value)
+{
+	UNIMPLEMENTED
+  return 0;
+}
+
+static char* gtkListGetSelectedTextAttrib(Ihandle* ih)
+{
+	UNIMPLEMENTED
+  return NULL;
+}
+
+static int gtkListSetCaretAttrib(Ihandle* ih, const char* value)
+{
+	UNIMPLEMENTED
+  return 0;
+}
+
+static char* gtkListGetCaretAttrib(Ihandle* ih)
+{
+	UNIMPLEMENTED
+    return NULL;
+}
+
+static int gtkListSetCaretPosAttrib(Ihandle* ih, const char* value)
+{
+	UNIMPLEMENTED
+  return 0;
+}
+
+static char* gtkListGetCaretPosAttrib(Ihandle* ih)
+{
+	UNIMPLEMENTED
+    return NULL;
+}
+
+static int gtkListSetScrollToAttrib(Ihandle* ih, const char* value)
+{
+	UNIMPLEMENTED
+  return 0;
+}
+
+static int gtkListSetScrollToPosAttrib(Ihandle* ih, const char* value)
+{
+	UNIMPLEMENTED
+  return 0;
+}
+
+static int gtkListSetInsertAttrib(Ihandle* ih, const char* value)
+{
+	UNIMPLEMENTED
+  return 0;
+}
+
+static int gtkListSetAppendAttrib(Ihandle* ih, const char* value)
+{
+	UNIMPLEMENTED
+  return 0;
+}
+
+static int gtkListSetNCAttrib(Ihandle* ih, const char* value)
+{
+	UNIMPLEMENTED
+    return 1; /* store until not mapped, when mapped will be set again */
+}
+
+static int gtkListSetClipboardAttrib(Ihandle *ih, const char *value)
+{
+	UNIMPLEMENTED
+  return 0;
+}
+
+static int gtkListSetReadOnlyAttrib(Ihandle* ih, const char* value)
+{
+	UNIMPLEMENTED
+  return 0;
+}
+
+static char* gtkListGetReadOnlyAttrib(Ihandle* ih)
+{
+	UNIMPLEMENTED
+    return "NO";
+}
+
+static int gtkListSetImageAttrib(Ihandle* ih, int id, const char* value)
+{
+	UNIMPLEMENTED
+  return 0;
+}
+
+void* iupdrvListGetImageHandle(Ihandle* ih, int id)
+{
+	UNIMPLEMENTED
+		return NULL;
+}
+
+/*********************************************************************************/
+
+static int beListMapMethod(Ihandle* ih)
+{
+  if (ih->data->is_dropdown)
+  {
+	BMenu* menu = new BMenu("");
+	menu->SetLabelFromMarked(true);
+	ih->handle = (InativeHandle*)new BMenuField(BRect(0,0,10,10), "PopUpMenu", NULL, menu);
+  } else {
+	BListView* widget = new BListView(BRect(0, 0, 10,10), "ListView",
+	  B_SINGLE_SELECTION_LIST, B_FOLLOW_ALL_SIDES);
+    ih->handle = (InativeHandle*)widget;
+
+	BMessage* msg;
+    msg = new BMessage(listInvoke);
+	msg->AddPointer("iHandle", ih);
+	widget->SetInvocationMessage(msg);
+
+	msg = new BMessage(listSelect);
+	msg->AddPointer("iHandle", ih);
+	widget->SetSelectionMessage(msg);
+
+    if (ih->data->sb)
+    {
+      ih->handle = (InativeHandle*)new BScrollView("scrolllist",
+		(BView*)ih->handle, B_FOLLOW_LEFT | B_FOLLOW_TOP, 0, false, true);
+    }
+  }
+
+  if(ih->data->show_image)
+	UNIMPLEMENTED
+
+  if (ih->data->has_editbox)
+	UNIMPLEMENTED
+
+  iuphaikuBaseAddToParent(ih);
+
+  iupListSetInitialItems(ih);
+  return IUP_NOERROR;
+}
+
+void iupdrvListInitClass(Iclass* ic)
+{
+  /* Driver Dependent Class functions */
+  ic->Map = beListMapMethod;
+
+  /* Driver Dependent Attribute functions */
+
+  /* Overwrite Common */
+// TODO does the common code actually works for lists ? We may need to iterate
+// over the stringitems and set the font for each of them ?
+//  iupClassRegisterAttribute(ic, "STANDARDFONT", NULL, gtkListSetStandardFontAttrib, IUPAF_SAMEASSYSTEM, "DEFAULTFONT", IUPAF_NO_SAVE|IUPAF_NOT_MAPPED);
+
+  /* Visual */
+  iupClassRegisterAttribute(ic, "BGCOLOR", NULL, gtkListSetBgColorAttrib, IUPAF_SAMEASSYSTEM, "TXTBGCOLOR", IUPAF_DEFAULT);
+
+  /* Special */
+  iupClassRegisterAttribute(ic, "FGCOLOR", NULL, gtkListSetFgColorAttrib, IUPAF_SAMEASSYSTEM, "TXTFGCOLOR", IUPAF_DEFAULT);
+
+  /* IupList only */
+  iupClassRegisterAttributeId(ic, "IDVALUE", haikuListGetIdValueAttrib, iupListSetIdValueAttrib, IUPAF_NO_INHERIT);
+  iupClassRegisterAttribute(ic, "VALUE", haikuListGetValueAttrib, gtkListSetValueAttrib, NULL, NULL, IUPAF_NO_DEFAULTVALUE|IUPAF_NO_INHERIT);
+  iupClassRegisterAttribute(ic, "SHOWDROPDOWN", NULL, gtkListSetShowDropdownAttrib, NULL, NULL, IUPAF_WRITEONLY|IUPAF_NO_INHERIT);
+  iupClassRegisterAttribute(ic, "TOPITEM", NULL, gtkListSetTopItemAttrib, NULL, NULL, IUPAF_NO_INHERIT);
+  iupClassRegisterAttribute(ic, "SPACING", iupListGetSpacingAttrib, gtkListSetSpacingAttrib, IUPAF_SAMEASSYSTEM, "0", IUPAF_NOT_MAPPED);
+
+  iupClassRegisterAttribute(ic, "PADDING", iupListGetPaddingAttrib, gtkListSetPaddingAttrib, IUPAF_SAMEASSYSTEM, "0x0", IUPAF_NOT_MAPPED);
+  iupClassRegisterAttribute(ic, "SELECTEDTEXT", gtkListGetSelectedTextAttrib, gtkListSetSelectedTextAttrib, NULL, NULL, IUPAF_NO_INHERIT);
+  iupClassRegisterAttribute(ic, "SELECTION", gtkListGetSelectionAttrib, gtkListSetSelectionAttrib, NULL, NULL, IUPAF_NO_INHERIT);
+  iupClassRegisterAttribute(ic, "SELECTIONPOS", gtkListGetSelectionPosAttrib, gtkListSetSelectionPosAttrib, NULL, NULL, IUPAF_NO_INHERIT);
+  iupClassRegisterAttribute(ic, "CARET", gtkListGetCaretAttrib, gtkListSetCaretAttrib, NULL, NULL, IUPAF_NO_SAVE|IUPAF_NO_INHERIT);
+  iupClassRegisterAttribute(ic, "CARETPOS", gtkListGetCaretPosAttrib, gtkListSetCaretPosAttrib, IUPAF_SAMEASSYSTEM, "0", IUPAF_NO_SAVE|IUPAF_NO_INHERIT);
+  iupClassRegisterAttribute(ic, "INSERT", NULL, gtkListSetInsertAttrib, NULL, NULL, IUPAF_WRITEONLY|IUPAF_NO_INHERIT);
+  iupClassRegisterAttribute(ic, "APPEND", NULL, gtkListSetAppendAttrib, NULL, NULL, IUPAF_WRITEONLY|IUPAF_NO_INHERIT);
+  iupClassRegisterAttribute(ic, "READONLY", gtkListGetReadOnlyAttrib, gtkListSetReadOnlyAttrib, NULL, NULL, IUPAF_DEFAULT);
+  iupClassRegisterAttribute(ic, "NC", iupListGetNCAttrib, gtkListSetNCAttrib, NULL, NULL, IUPAF_NOT_MAPPED);
+  iupClassRegisterAttribute(ic, "CLIPBOARD", NULL, gtkListSetClipboardAttrib, NULL, NULL, IUPAF_NO_INHERIT);
+  iupClassRegisterAttribute(ic, "SCROLLTO", NULL, gtkListSetScrollToAttrib, NULL, NULL, IUPAF_WRITEONLY|IUPAF_NO_INHERIT);
+  iupClassRegisterAttribute(ic, "SCROLLTOPOS", NULL, gtkListSetScrollToPosAttrib, NULL, NULL, IUPAF_WRITEONLY|IUPAF_NO_INHERIT);
+
+  iupClassRegisterAttributeId(ic, "IMAGE", NULL, gtkListSetImageAttrib, IUPAF_IHANDLENAME|IUPAF_WRITEONLY|IUPAF_NO_INHERIT);
+
+  /* Not Supported */
+  iupClassRegisterAttribute(ic, "VISIBLE_ITEMS", NULL, NULL, IUPAF_SAMEASSYSTEM, "5", IUPAF_NOT_SUPPORTED);
+  iupClassRegisterAttribute(ic, "DROPEXPAND", NULL, NULL, IUPAF_SAMEASSYSTEM, "Yes", IUPAF_NOT_SUPPORTED|IUPAF_NO_INHERIT);
+  iupClassRegisterAttribute(ic, "AUTOREDRAW", NULL, NULL, IUPAF_SAMEASSYSTEM, "Yes", IUPAF_NOT_SUPPORTED|IUPAF_NO_INHERIT);
+}
+
+// Event handlers
+
+void iuphaikuListInvoked(Ihandle* ih, int item)
+{
+  IFnis cb = (IFnis) IupGetCallback(ih, "DBLCLICK_CB");
+  if (cb)
+  {
+    iupListSingleCallDblClickCallback(ih, cb, item+1);  /* IUP starts at 1 */
+  }
+}
+
+void iuphaikuListSelected(Ihandle* ih, int item)
+{
+  if (ih->data->has_editbox)
+  {
+    /* must manually update its contents */
+	UNIMPLEMENTED
+  }
+
+  if (!ih->data->is_multiple)
+  {
+    IFnsii cb = (IFnsii) IupGetCallback(ih, "ACTION");
+    if (cb)
+    {
+      iupListSingleCallActionCallback(ih, cb, item+1);  /* IUP starts at 1 */
+    }
+  } else {
+    IFns multi_cb = (IFns)IupGetCallback(ih, "MULTISELECT_CB");
+    IFnsii cb = (IFnsii) IupGetCallback(ih, "ACTION");
+    if (multi_cb || cb)
+    {
+	  UNIMPLEMENTED
+	}
+  }
+}
diff --git a/src/haiku/iuphaiku_loop.cpp b/src/haiku/iuphaiku_loop.cpp
new file mode 100644
index 0000000..db60cb5
--- /dev/null
+++ b/src/haiku/iuphaiku_loop.cpp
@@ -0,0 +1,109 @@
+/** \file
+ * \brief GTK Message Loop
+ *
+ * See Copyright Notice in "iup.h"
+ */
+
+#include <stdio.h>    
+#include <string.h>    
+
+#include <Application.h>
+#include <MessageQueue.h>
+#include <Window.h>
+
+#include "iup.h"
+#include "iupcbs.h"
+
+#define UNIMPLEMENTED printf("%s (%s %d) UNIMPLEMENTED\n",__func__,__FILE__,__LINE__);
+
+static IFidle haiku_idle_cb = NULL;
+
+extern "C" {
+void iupdrvSetIdleFunction(Icallback f)
+{
+  haiku_idle_cb = (IFidle)f;
+  if (f != NULL)
+    UNIMPLEMENTED
+}
+}
+
+void IupExitLoop(void)
+{
+  be_app->PostMessage(B_QUIT_REQUESTED);
+}
+
+int IupMainLoopLevel(void)
+{
+	UNIMPLEMENTED
+		return 0;
+}
+
+static bool isRunning = false;
+
+int IupMainLoop(void)
+{
+  // This is called for the main window (and we start the application), but
+  // also for all modal dialogs. We can only start the application once, so
+  // when this function gets called again it should instead wait for the
+  // last opened dialog to close...
+  // TODO how do we manage the callback from setIdleFunction ?
+  if(!isRunning)
+  {
+	isRunning = true;
+    be_app->Run();
+  } else {
+	// FIXME not so good design here. We're locking the calling thread (likely
+	// a BWindow) which means it will not be able to receive any messages as
+	// long as the modal dialog is open. This includes redraw messages as well
+	// so the window will get drawing artifacts...
+	// But if we return from this method, the dialog will be closed by IUP.
+	// We likely need to do some changes to IUP dialog code to get it right.
+    BWindow* win = be_app->WindowAt(be_app->CountWindows() - 1);
+	thread_id tid = win->Thread();
+	status_t result;
+	wait_for_thread(tid, &result);
+  }
+  return IUP_NOERROR;
+}
+
+int IupLoopStepWait(void)
+{
+	UNIMPLEMENTED
+  return IUP_DEFAULT;
+}
+
+int32 appLoop(void*)
+{
+	be_app->LockLooper();
+	be_app->Run();
+}
+
+int IupLoopStep(void)
+{
+  if(!isRunning) {
+	isRunning = true;
+	thread_id id = spawn_thread(appLoop, "IUP Application", B_NORMAL_PRIORITY, NULL);
+	resume_thread(id);
+	be_app->UnlockLooper();
+  }
+
+  BLooper* looper = BLooper::LooperForThread(find_thread(NULL));
+  if (looper == NULL)
+	  return IUP_DEFAULT;
+
+  BMessage* msg = looper->MessageQueue()->NextMessage();
+  if (msg != NULL) {
+	msg->PrintToStream();
+    looper->MessageReceived(msg);
+  } else {
+	puts("no messages");
+  }
+  return IUP_DEFAULT;
+}
+
+void IupFlush(void)
+{
+	// This is meant to flush the event loop. Since the windows each run in
+	// their own thread, we can't do much anyway. Let's see later if this is a
+	// real problem...
+}
diff --git a/src/haiku/iuphaiku_menu.cpp b/src/haiku/iuphaiku_menu.cpp
new file mode 100644
index 0000000..fc86e91
--- /dev/null
+++ b/src/haiku/iuphaiku_menu.cpp
@@ -0,0 +1,273 @@
+/** \file
+ * \brief Menu Resources
+ *
+ * See Copyright Notice in "iup.h"
+ */
+
+#define UNIMPLEMENTED printf("%s (%s %d) UNIMPLEMENTED\n",__func__,__FILE__,__LINE__);
+
+#include <MenuBar.h>
+#include <MenuItem.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <memory.h>
+#include <stdarg.h>
+
+#include "iup.h"
+#include "iupcbs.h"
+
+#include "iup_object.h"
+#include "iup_childtree.h"
+#include "iup_attrib.h"
+#include "iup_dialog.h"
+#include "iup_str.h"
+#include "iup_label.h"
+#include "iup_drv.h"
+#include "iup_drvfont.h"
+#include "iup_image.h"
+#include "iup_menu.h"
+
+#include "iuphaiku_drv.h"
+
+
+typedef struct _ImenuPos
+{
+  int x, y;
+} ImenuPos;
+
+int iupdrvMenuPopup(Ihandle* ih, int x, int y)
+{
+	UNIMPLEMENTED
+  return IUP_NOERROR;
+}
+
+int iupdrvMenuGetMenuBarSize(Ihandle* ih)
+{
+  int ch;
+  iupdrvFontGetCharSize(ih, NULL, &ch);
+  return 4 + ch + 4;
+}
+
+/*******************************************************************************************/
+
+
+static int haikuMenuMapMethod(Ihandle* ih)
+{
+  if (iupMenuIsMenuBar(ih))
+  {
+    /* top level menu used for MENU attribute in IupDialog (a menu bar) */
+    ih->handle = (InativeHandle*)new BMenuBar(BRect(0, 0, 10, 10), "IUPMenuBar");
+    if (!ih->handle)
+      return IUP_ERROR;
+
+    iuphaikuBaseAddToParent(ih);
+  }
+  else
+  {
+    if (ih->parent)
+    {
+	  // Menu was already created with the SubMenu. Just set the handle now.
+	  BMenuItem* item = (BMenuItem*)ih->parent->handle;
+      ih->handle = (InativeHandle*)(item->Submenu());
+      if (!ih->handle)
+        return IUP_ERROR;
+    }
+    else
+    {
+      /* top level menu used for IupPopup */
+	  UNIMPLEMENTED;
+    }
+  }
+
+  //gtk_widget_add_events(ih->handle, GDK_KEY_PRESS_MASK);
+  //g_signal_connect(G_OBJECT(ih->handle), "key-press-event", G_CALLBACK(gtkMenuKeyPressEvent), ih);
+
+  ih->serial = iupMenuGetChildId(ih); 
+  //gtk_widget_show(ih->handle);
+
+  return IUP_NOERROR;
+}
+
+static void gtkMenuUnMapMethod(Ihandle* ih)
+{
+  if (iupMenuIsMenuBar(ih))
+    ih->parent = NULL;
+
+  iupdrvBaseUnMapMethod(ih);
+}
+
+void iupdrvMenuInitClass(Iclass* ic)
+{
+  /* Driver Dependent Class functions */
+  ic->Map = haikuMenuMapMethod;
+  ic->UnMap = gtkMenuUnMapMethod;
+
+  /* Used by iupdrvMenuGetMenuBarSize */
+  iupClassRegisterAttribute(ic, "STANDARDFONT", NULL, NULL, IUPAF_SAMEASSYSTEM, "DEFAULTFONT", IUPAF_NO_SAVE|IUPAF_DEFAULT);  /* use inheritance to retrieve standard fonts */
+
+  iupClassRegisterAttribute(ic, "BGCOLOR", NULL, iupdrvBaseSetBgColorAttrib, NULL, NULL, IUPAF_DEFAULT);
+}
+
+
+/*******************************************************************************************/
+
+static int gtkItemSetTitleImageAttrib(Ihandle* ih, const char* value)
+{
+	UNIMPLEMENTED
+    return 0;
+}
+
+static int gtkItemSetImageAttrib(Ihandle* ih, const char* value)
+{
+	UNIMPLEMENTED
+    return 0;
+}
+
+static int gtkItemSetImpressAttrib(Ihandle* ih, const char* value)
+{
+	UNIMPLEMENTED
+    return 0;
+}
+
+static int gtkItemSetTitleAttrib(Ihandle* ih, const char* value)
+{
+  BMenuItem* item = (BMenuItem*)ih->handle;
+  item->SetLabel(value);
+  return 1;
+}
+
+static int gtkItemSetValueAttrib(Ihandle* ih, const char* value)
+{
+    if (iupAttribGetBoolean(ih->parent, "RADIO"))
+      value = "ON";
+
+	BMenuItem* item = (BMenuItem*)ih->handle;
+	item->SetMarked(iupStrBoolean(value));
+
+	// TODO handle images items
+
+    return 0;
+}
+
+static char* gtkItemGetValueAttrib(Ihandle* ih)
+{
+	BMenuItem* item = (BMenuItem*)ih->handle;
+	return (char*)(item->IsMarked() ? "ON":"OFF");
+}
+
+static int gtkItemMapMethod(Ihandle* ih)
+{
+  if (!ih->parent)
+    return IUP_ERROR;
+
+  BMenu* parent = dynamic_cast<BMenu*>((BView*)ih->parent->handle);
+  char* title = iupAttribGet(ih, "TITLE");
+
+  BMessage* msg = new BMessage(menuInvoke);
+  msg->AddPointer("iHandle", ih);
+  BMenuItem* child = new BMenuItem(title, msg);
+  ih->handle = (InativeHandle*)child;
+
+  int pos = IupGetChildPos(ih->parent, ih);
+  parent->AddItem(child, pos);
+
+  return IUP_NOERROR;
+}
+
+void iupdrvItemInitClass(Iclass* ic)
+{
+  /* Driver Dependent Class functions */
+  ic->Map = gtkItemMapMethod;
+  ic->UnMap = iupdrvBaseUnMapMethod;
+
+  /* Common */
+  iupClassRegisterAttribute(ic, "STANDARDFONT", NULL, iupdrvSetStandardFontAttrib, IUPAF_SAMEASSYSTEM, "DEFAULTFONT", IUPAF_NO_SAVE|IUPAF_NOT_MAPPED);  /* use inheritance to retrieve standard fonts */
+
+  /* Visual */
+  iupClassRegisterAttribute(ic, "ACTIVE", iupBaseGetActiveAttrib, iupBaseSetActiveAttrib, IUPAF_SAMEASSYSTEM, "YES", IUPAF_DEFAULT);
+  iupClassRegisterAttribute(ic, "BGCOLOR", NULL, iupdrvBaseSetBgColorAttrib, IUPAF_SAMEASSYSTEM, "DLGBGCOLOR", IUPAF_DEFAULT);
+
+  /* IupItem only */
+  iupClassRegisterAttribute(ic, "VALUE", gtkItemGetValueAttrib, gtkItemSetValueAttrib, NULL, NULL, IUPAF_NO_DEFAULTVALUE|IUPAF_NO_INHERIT);
+  iupClassRegisterAttribute(ic, "TITLE", NULL, gtkItemSetTitleAttrib, NULL, NULL, IUPAF_NO_DEFAULTVALUE|IUPAF_NO_INHERIT);
+  iupClassRegisterAttribute(ic, "TITLEIMAGE", NULL, gtkItemSetTitleImageAttrib, NULL, NULL, IUPAF_NO_DEFAULTVALUE|IUPAF_NO_INHERIT);
+  iupClassRegisterAttribute(ic, "IMAGE", NULL, gtkItemSetImageAttrib, NULL, NULL, IUPAF_IHANDLENAME|IUPAF_NO_DEFAULTVALUE|IUPAF_NO_INHERIT);
+  iupClassRegisterAttribute(ic, "IMPRESS", NULL, gtkItemSetImpressAttrib, NULL, NULL, IUPAF_IHANDLENAME|IUPAF_NO_DEFAULTVALUE|IUPAF_NO_INHERIT);
+
+  /* IupItem GTK and Motif only */
+  iupClassRegisterAttribute(ic, "HIDEMARK", NULL, NULL, NULL, NULL, IUPAF_NOT_MAPPED);
+}
+
+
+/*******************************************************************************************/
+
+
+static int gtkSubmenuSetImageAttrib(Ihandle* ih, const char* value)
+{
+	UNIMPLEMENTED
+    return 0;
+}
+
+static int haikuSubmenuMapMethod(Ihandle* ih)
+{
+  if (!ih->parent)
+    return IUP_ERROR;
+
+  char* title = iupAttribGet(ih, "TITLE");
+  BMenuItem* item = new BMenuItem(new BMenu(title), NULL);
+  ih->handle = (InativeHandle*)item;
+
+  BMenu* topmenu = (BMenu*)ih->parent->handle;
+  int pos = IupGetChildPos(ih->parent, ih);
+  topmenu->AddItem(item, pos);
+  
+  //iupUpdateStandardFontAttrib(ih);
+
+  return IUP_NOERROR;
+}
+
+void iupdrvSubmenuInitClass(Iclass* ic)
+{
+  /* Driver Dependent Class functions */
+  ic->Map = haikuSubmenuMapMethod;
+  ic->UnMap = iupdrvBaseUnMapMethod;
+
+  /* Common */
+  iupClassRegisterAttribute(ic, "STANDARDFONT", NULL, iupdrvSetStandardFontAttrib, IUPAF_SAMEASSYSTEM, "DEFAULTFONT", IUPAF_NO_SAVE|IUPAF_NOT_MAPPED);  /* use inheritance to retrieve standard fonts */
+
+  /* Visual */
+  iupClassRegisterAttribute(ic, "ACTIVE", iupBaseGetActiveAttrib, iupBaseSetActiveAttrib, IUPAF_SAMEASSYSTEM, "YES", IUPAF_DEFAULT);
+  iupClassRegisterAttribute(ic, "BGCOLOR", NULL, iupdrvBaseSetBgColorAttrib, IUPAF_SAMEASSYSTEM, "DLGBGCOLOR", IUPAF_DEFAULT);
+
+  /* IupSubmenu only */
+  iupClassRegisterAttribute(ic, "TITLE", NULL, gtkItemSetTitleAttrib, NULL, NULL, IUPAF_NO_DEFAULTVALUE|IUPAF_NO_INHERIT);
+  iupClassRegisterAttribute(ic, "IMAGE", NULL, gtkSubmenuSetImageAttrib, NULL, NULL, IUPAF_IHANDLENAME|IUPAF_NO_DEFAULTVALUE|IUPAF_NO_INHERIT);
+}
+
+
+/*******************************************************************************************/
+
+
+static int gtkSeparatorMapMethod(Ihandle* ih)
+{
+
+  if (!ih->parent)
+    return IUP_ERROR;
+
+  ih->handle = (InativeHandle*)new BSeparatorItem();
+
+  BMenu* parent = dynamic_cast<BMenu*>((BView*)ih->parent->handle);
+  int pos = IupGetChildPos(ih->parent, ih);
+  parent->AddItem((BSeparatorItem*)ih->handle, pos);
+  
+  return IUP_NOERROR;
+}
+
+void iupdrvSeparatorInitClass(Iclass* ic)
+{
+  /* Driver Dependent Class functions */
+  ic->Map = gtkSeparatorMapMethod;
+  ic->UnMap = iupdrvBaseUnMapMethod;
+}
diff --git a/src/haiku/iuphaiku_messagedlg.c b/src/haiku/iuphaiku_messagedlg.c
new file mode 100644
index 0000000..6c7f487
--- /dev/null
+++ b/src/haiku/iuphaiku_messagedlg.c
@@ -0,0 +1,38 @@
+/** \file
+ * \brief GTK IupMessageDlg pre-defined dialog
+ *
+ * See Copyright Notice in "iup.h"
+ */
+
+#include "iup.h"
+
+#include "iup_object.h"
+#include "iup_attrib.h"
+#include "iup_str.h"
+#include "iup_dialog.h"
+
+#include "iuphaiku_drv.h"
+
+#include <stdio.h>
+#define UNIMPLEMENTED printf("%s (%s %d) UNIMPLEMENTED\n",__func__,__FILE__,__LINE__);
+
+/* Sometimes GTK decides to invert the buttons position because of the GNOME Guidelines.
+   To avoid that we define different Ids for the buttons. */
+#define IUP_RESPONSE_1 -100
+#define IUP_RESPONSE_2 -200
+#define IUP_RESPONSE_HELP -300
+
+#ifndef GTK_MESSAGE_OTHER
+#define GTK_MESSAGE_OTHER GTK_MESSAGE_INFO
+#endif
+
+static int gtkMessageDlgPopup(Ihandle* ih, int x, int y)
+{
+	UNIMPLEMENTED
+  return IUP_NOERROR;
+}
+
+void iupdrvMessageDlgInitClass(Iclass* ic)
+{
+  ic->DlgPopup = gtkMessageDlgPopup;
+}
diff --git a/src/haiku/iuphaiku_open.cpp b/src/haiku/iuphaiku_open.cpp
new file mode 100644
index 0000000..badd7c7
--- /dev/null
+++ b/src/haiku/iuphaiku_open.cpp
@@ -0,0 +1,114 @@
+/** \file
+ * \brief GTK Driver Core
+ *
+ * See Copyright Notice in "iup.h"
+ */
+
+#include <stdio.h>          
+#include <stdlib.h>
+#include <string.h>
+
+#include <Application.h>
+#include <Screen.h>
+#include <View.h>
+
+#define UNIMPLEMENTED printf("%s (%s %d) UNIMPLEMENTED\n",__func__,__FILE__,__LINE__);
+
+#include "iup.h"
+
+#include "iup_str.h"
+#include "iup_drv.h"
+#include "iup_drvinfo.h"
+#include "iup_object.h"
+#include "iup_globalattrib.h"
+
+#include "iuphaiku_drv.h"
+
+char* iupgtkGetNativeWindowHandle(Ihandle* ih)
+{
+  BView* view = (BView*)ih->handle;
+  return (char*)view->Window();
+}
+
+void* iupdrvGetDisplay(void)
+{
+  return new BScreen(); // TODO Does this leak memory ?
+}
+
+void iupgtkPushVisualAndColormap(void* visual, void* colormap)
+{
+	UNIMPLEMENTED
+}
+
+extern void iuphaikuTimerFired(Ihandle* ih);
+
+class IUPApplication: public BApplication
+{
+	public:
+		IUPApplication()
+			: BApplication("application/iup")
+		{
+		}
+
+	  	void MessageReceived(BMessage* message)
+		{
+			Ihandle* ih = NULL;
+			message->FindPointer("iHandle", (void**)&ih);
+
+			switch(message->what) {
+	  			case timerFire:
+					iuphaikuTimerFired(ih);
+					break;
+				default:
+					BApplication::MessageReceived(message);
+					break;
+			}
+		}
+};
+
+
+static void haikuSetGlobalAttrib(void)
+{
+	// XDISPLAY, XSCREEN, XSERVERVENDOR, XVENDORRELEASE
+}
+
+
+void haikuSetGlobalColors(void)
+{
+	rgb_color color;
+	color = ui_color(B_PANEL_BACKGROUND_COLOR); // or B_CONTROL_BACKGROUND_COLOR ?
+	iupGlobalSetDefaultColorAttrib("DLGBGCOLOR", color.red, color.green, color.blue);
+	color = ui_color(B_PANEL_TEXT_COLOR); // or B_CONTROL_TEXT_COLOR ?
+	iupGlobalSetDefaultColorAttrib("DLFBGCOLOR", color.red, color.green, color.blue);
+	color = ui_color(B_DOCUMENT_BACKGROUND_COLOR);
+	iupGlobalSetDefaultColorAttrib("TXTBGCOLOR", color.red, color.green, color.blue);
+	color = ui_color(B_DOCUMENT_TEXT_COLOR);
+	iupGlobalSetDefaultColorAttrib("TXTFGCOLOR", color.red, color.green, color.blue);
+}
+
+
+int iupdrvOpen(int *argc, char ***argv)
+{
+  IupSetGlobal("DRIVER", "HAIKU");
+  //IupStoreGlobal("SYSTEMLANGUAGE", pango_language_to_string(gtk_get_default_language()));
+  //HAIKUVERSION ? (does that make any sense ?)
+  
+  haikuSetGlobalAttrib();
+
+  haikuSetGlobalColors();
+
+  // Here, create our BApplication.
+  new IUPApplication();
+
+  return IUP_NOERROR;
+}
+
+void iupdrvClose(void)
+{
+  // Here, destroy our BApplication.
+  if (be_app)
+  {
+  	be_app->Lock();
+  	be_app->Quit();
+  }
+}
diff --git a/src/haiku/iuphaiku_progressbar.cpp b/src/haiku/iuphaiku_progressbar.cpp
new file mode 100644
index 0000000..c5da813
--- /dev/null
+++ b/src/haiku/iuphaiku_progressbar.cpp
@@ -0,0 +1,105 @@
+/** \file
+* \brief Progress bar Control
+*
+* See Copyright Notice in "iup.h"
+*/
+
+#define UNIMPLEMENTED printf("%s (%s %d) UNIMPLEMENTED\n",__func__,__FILE__,__LINE__);
+
+#include <StatusBar.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <memory.h>
+#include <stdarg.h>
+
+#include "iup.h"
+#include "iupcbs.h"
+
+#include "iup_object.h"
+#include "iup_layout.h"
+#include "iup_attrib.h"
+#include "iup_str.h"
+#include "iup_progressbar.h"
+#include "iup_drv.h"
+
+#include "iuphaiku_drv.h"
+
+static int haikuProgressBarSetValueAttrib(Ihandle* ih, const char* value)
+{
+  if (ih->data->marquee)
+    return 0;
+
+  if (!value)
+    ih->data->value = 0;
+  else
+    ih->data->value = atof(value);
+  iProgressBarCropValue(ih);
+
+  BStatusBar* bar = (BStatusBar*)ih->handle;
+  float val = bar->CurrentValue();
+  bar->Update(ih->data->value - val);
+
+  return 1;
+}
+
+static int haikuProgressBarSetMaxAttrib(Ihandle* ih, const char* value)
+{
+  if (ih->data->marquee)
+    return 0;
+
+  if (!value)
+    ih->data->vmax = 1;
+  else
+    ih->data->vmax = atof(value);
+  iProgressBarCropValue(ih);
+
+  BStatusBar* bar = (BStatusBar*)ih->handle;
+  bar->SetMaxValue(ih->data->vmax);
+
+  return 1;
+}
+
+static int haikuProgressBarMapMethod(Ihandle* ih)
+{
+  BStatusBar* bar = new BStatusBar(BRect(0,0,200,30), "progress");
+  bar->SetFlags(bar->Flags() | B_SUPPORTS_LAYOUT);
+  	// We need this to allow the bar to have no labels
+
+  bar->SetMaxValue(1.0f);
+
+  ih->handle = (InativeHandle*)bar;
+  
+  if (iupStrEqualNoCase(iupAttribGetStr(ih, "ORIENTATION"), "VERTICAL"))
+	UNIMPLEMENTED
+
+  if (iupAttribGetBoolean(ih, "MARQUEE"))
+	UNIMPLEMENTED
+
+  iuphaikuBaseAddToParent(ih);
+  return IUP_NOERROR;
+}
+
+
+static void haikuProgressLayoutUpdateMethod(Ihandle *ih)
+{
+  iupdrvBaseLayoutUpdateMethod(ih);
+
+  BStatusBar* bar = (BStatusBar*)ih->handle;
+  bar->SetBarHeight(ih->currentheight - 1);
+}
+
+
+void iupdrvProgressBarInitClass(Iclass* ic)
+{
+  /* Driver Dependent Class functions */
+  ic->Map = haikuProgressBarMapMethod;
+  ic->LayoutUpdate = haikuProgressLayoutUpdateMethod;
+  
+  // TODO Callbacks : BGCOLOR, FGCOLOR, DASHED, ORIENTATION, MARQUEE
+
+  /* IupProgressBar only */
+  iupClassRegisterAttribute(ic, "VALUE",  iProgressBarGetValueAttrib,  haikuProgressBarSetValueAttrib,  NULL, NULL, IUPAF_NO_DEFAULTVALUE|IUPAF_NO_INHERIT);
+  iupClassRegisterAttribute(ic, "MAX",  NULL,  haikuProgressBarSetMaxAttrib,  NULL, NULL, IUPAF_NO_DEFAULTVALUE|IUPAF_NO_INHERIT);
+}
diff --git a/src/haiku/iuphaiku_tabs.cpp b/src/haiku/iuphaiku_tabs.cpp
new file mode 100644
index 0000000..072591a
--- /dev/null
+++ b/src/haiku/iuphaiku_tabs.cpp
@@ -0,0 +1,389 @@
+/** \file
+* \brief Tabs Control
+*
+* See Copyright Notice in "iup.h"
+*/
+
+#define UNIMPLEMENTED printf("%s (%s %d) UNIMPLEMENTED\n",__func__,__FILE__,__LINE__);
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+#include <memory.h>
+#include <stdarg.h>
+
+#include <TabView.h>
+
+#include "iup.h"
+#include "iupcbs.h"
+
+#include "iup_object.h"
+#include "iup_layout.h"
+#include "iup_attrib.h"
+#include "iup_str.h"
+#include "iup_dialog.h"
+#include "iup_drv.h"
+#include "iup_drvfont.h"
+#include "iup_stdcontrols.h"
+#include "iup_image.h"
+#include "iup_tabs.h"
+
+#include "iuphaiku_drv.h"
+
+
+int iupdrvTabsExtraDecor(Ihandle* ih)
+{
+  (void)ih;
+  return 0;
+}
+
+int iupdrvTabsGetLineCountAttrib(Ihandle* ih)
+{
+  (void)ih;
+  return 1;
+}
+
+void iupdrvTabsSetCurrentTab(Ihandle* ih, int pos)
+{
+	UNIMPLEMENTED
+}
+
+int iupdrvTabsGetCurrentTab(Ihandle* ih)
+{
+  BTabView* tv = (BTabView*)ih->handle;
+  return tv->Selection();
+}
+
+static void gtkTabsUpdatePageFont(Ihandle* ih)
+{
+	UNIMPLEMENTED
+}
+
+static void gtkTabsUpdatePageBgColor(Ihandle* ih, unsigned char r, unsigned char g, unsigned char b)
+{
+	UNIMPLEMENTED
+}
+
+static void gtkTabsUpdatePageFgColor(Ihandle* ih, unsigned char r, unsigned char g, unsigned char b)
+{
+	UNIMPLEMENTED
+}
+
+static void gtkTabsUpdatePagePadding(Ihandle* ih)
+{
+	UNIMPLEMENTED
+}
+
+/* ------------------------------------------------------------------------- */
+/* gtkTabs - Sets and Gets accessors                                         */
+/* ------------------------------------------------------------------------- */
+
+  
+static int gtkTabsSetPaddingAttrib(Ihandle* ih, const char* value)
+{
+  iupStrToIntInt(value, &ih->data->horiz_padding, &ih->data->vert_padding, 'x');
+
+  if (ih->handle)
+  {
+    gtkTabsUpdatePagePadding(ih);
+    return 0;
+  }
+  else
+    return 1; /* store until not mapped, when mapped will be set again */
+}
+
+static void gtkTabsUpdateTabType(Ihandle* ih)
+{
+	UNIMPLEMENTED
+}
+
+static int gtkTabsSetTabTypeAttrib(Ihandle* ih, const char* value)
+{
+  if(iupStrEqualNoCase(value, "BOTTOM"))
+    ih->data->type = ITABS_BOTTOM;
+  else if(iupStrEqualNoCase(value, "LEFT"))
+    ih->data->type = ITABS_LEFT;
+  else if(iupStrEqualNoCase(value, "RIGHT"))
+    ih->data->type = ITABS_RIGHT;
+  else /* "TOP" */
+    ih->data->type = ITABS_TOP;
+
+  if (ih->handle)
+    gtkTabsUpdateTabType(ih);  /* for this to work must be updated in map */
+
+  return 0;
+}
+
+static int gtkTabsSetTabOrientationAttrib(Ihandle* ih, const char* value)
+{
+  if (ih->handle) /* allow to set only before mapping */
+    return 0;
+
+  if(iupStrEqualNoCase(value, "VERTICAL"))
+    ih->data->orientation = ITABS_VERTICAL;
+  else  /* HORIZONTAL */
+    ih->data->orientation = ITABS_HORIZONTAL;
+
+  return 0;
+}
+
+static int haikuTabsSetTabTitleAttrib(Ihandle* ih, int pos, const char* value)
+{
+  if (value)
+  {
+    BTabView* tv = (BTabView*)ih->handle;
+	BTab* tab = tv->TabAt(pos);
+	tab->SetLabel(value);
+  }
+  
+  return 1;
+}
+
+static int gtkTabsSetTabImageAttrib(Ihandle* ih, int pos, const char* value)
+{
+	UNIMPLEMENTED
+  return 1;
+}
+
+static int gtkTabsSetStandardFontAttrib(Ihandle* ih, const char* value)
+{
+  iupdrvSetStandardFontAttrib(ih, value);
+  if (ih->handle)
+    gtkTabsUpdatePageFont(ih);
+  return 1;
+}
+
+static int gtkTabsSetFgColorAttrib(Ihandle* ih, const char* value)
+{
+  unsigned char r, g, b;
+  if (!iupStrToRGB(value, &r, &g, &b))
+    return 0;
+
+  iuphaikuBaseSetFgColor(ih->handle, r, g, b);
+  gtkTabsUpdatePageFgColor(ih, r, g, b);
+
+  return 1;
+}
+
+static int gtkTabsSetBgColorAttrib(Ihandle* ih, const char* value)
+{
+  unsigned char r, g, b;
+  if (!iupStrToRGB(value, &r, &g, &b))
+    return 0;
+
+  iuphaikuBaseSetBgColor(ih->handle, r, g, b);
+  gtkTabsUpdatePageBgColor(ih, r, g, b);
+
+  return 1;
+}
+
+
+/* ------------------------------------------------------------------------- */
+/* gtkTabs - Methods and Init Class                                          */
+/* ------------------------------------------------------------------------- */
+
+static void haikuTabsChildAddedMethod(Ihandle* ih, Ihandle* child)
+{
+  if (IupGetName(child) == NULL)
+    iupAttribSetHandleName(child);
+
+  if (ih->handle)
+  {
+	BTabView* tv = (BTabView*)ih->handle;
+
+    const char *tabtitle, *tabimage;
+    int pos;
+
+    pos = IupGetChildPos(ih, child);
+
+	BTab* tab = new BTab((BView*)child->handle);
+
+	BView* view = new BView(
+		BRect(0, 0, ih->currentwidth, ih->currentheight),
+		"IUPTabHolder", B_FOLLOW_ALL_SIDES, 0);
+
+    tabtitle = iupTabsAttribGetStrId(ih, "TABTITLE", pos);
+    if (!tabtitle) 
+    {
+      tabtitle = iupAttribGet(child, "TABTITLE");
+      if (tabtitle)
+        iupTabsAttribSetStrId(ih, "TABTITLE", pos, tabtitle);
+    }
+
+    tabimage = iupTabsAttribGetStrId(ih, "TABIMAGE", pos);
+    if (!tabimage) 
+    {
+      tabimage = iupAttribGet(child, "TABIMAGE");
+      if (tabimage)
+        iupTabsAttribSetStrId(ih, "TABIMAGE", pos, tabimage);
+    }
+
+    if (!tabtitle && !tabimage)
+      tabtitle = "     ";
+
+    if (tabtitle)
+    {
+	  tab->SetLabel(tabtitle);
+    }
+
+    if (tabimage)
+    {
+		UNIMPLEMENTED
+      //GdkPixbuf* pixbuf = iupImageGetImage(tabimage, ih, 0);
+
+      //tab_image = gtk_image_new();
+
+      //if (pixbuf)
+      //  gtk_image_set_from_pixbuf((GtkImage*)tab_image, pixbuf);
+    }
+
+    if (tabimage && tabtitle)
+    {
+		UNIMPLEMENTED
+      //GtkWidget* box;
+	  /*
+      if (ih->data->orientation == ITABS_VERTICAL)
+        box = gtk_vbox_new(FALSE, 2);
+      else
+        box = gtk_hbox_new(FALSE, 2);
+      gtk_widget_show(box);
+
+      gtk_container_add((GtkContainer*)box, tab_image);
+      gtk_container_add((GtkContainer*)box, tab_label);
+
+      gtk_notebook_insert_page((GtkNotebook*)ih->handle, tab_page, box, pos);
+      gtk_notebook_set_menu_label_text((GtkNotebook*)ih->handle, tab_page, gtk_label_get_text((GtkLabel*)tab_label));
+	  */
+    }
+
+	// There is some breakage of the view hierarchy here. Haiku does not use the
+	// regular AddChild method for adding tabs to a BTabView, and IUP also doesn't
+	// use the regular way of looking for the parent native view. We need to add
+	// a top view for te whole tab and tell IUP explicitly that this is the
+	// parent view to use for the tab contents.
+    iupAttribSetStr(child, "_IUPTAB_CONTAINER", (char*)view);
+    iupAttribSetStr(child, "_IUPTAB_PAGE", (char*)tab);
+
+    unsigned char r, g, b;
+    iupStrToRGB(IupGetAttribute(ih, "BGCOLOR"), &r, &g, &b);
+    iuphaikuBaseSetBgColor((InativeHandle*)view, r, g, b);
+
+    //iupAttribSetStr(ih, "_IUPGTK_IGNORE_CHANGE", NULL);
+
+	tv->AddTab(view, tab);
+  }
+}
+
+static void gtkTabsChildRemovedMethod(Ihandle* ih, Ihandle* child)
+{
+	UNIMPLEMENTED
+}
+
+
+class IUPTabView: public BTabView
+{
+	public:
+		IUPTabView(Ihandle* handle)
+			: BTabView(BRect(0,0,10,10), "iuptabs")
+			, ih(handle)
+		{}
+
+		void Select(int32 newtab) {
+			int32 oldtab = Selection();
+
+			BTabView::Select(newtab);
+
+			IFnnn cb = (IFnnn)IupGetCallback(ih, "TABCHANGE_CB");
+			if (cb) {
+				Ihandle* child = IupGetChild(ih, newtab);
+				Ihandle* prev_child = IupGetChild(ih, oldtab);
+				cb(ih, child, prev_child);
+			} else
+			{
+				IFnii cb2 = (IFnii)IupGetCallback(ih, "TABCHANGEPOS_CB");
+				if (cb2)
+					cb2(ih, newtab, oldtab);
+			}
+		}
+	private:
+		Ihandle* ih;
+};
+
+
+static int haikuTabsMapMethod(Ihandle* ih)
+{
+  ih->handle = (InativeHandle*)new IUPTabView(ih);
+  if (!ih->handle)
+    return IUP_ERROR;
+
+  //gtk_notebook_set_scrollable((GtkNotebook*)ih->handle, TRUE);
+  //gtk_notebook_popup_enable((GtkNotebook*)ih->handle);
+
+  //gtkTabsUpdateTabType(ih);
+
+  /* add to the parent, all controls must call this. */
+  iuphaikuBaseAddToParent(ih);
+
+  /*
+  gtk_widget_add_events(ih->handle, GDK_ENTER_NOTIFY_MASK|GDK_LEAVE_NOTIFY_MASK);
+
+  g_signal_connect(G_OBJECT(ih->handle), "enter-notify-event",  G_CALLBACK(iupgtkEnterLeaveEvent), ih);
+  g_signal_connect(G_OBJECT(ih->handle), "leave-notify-event",  G_CALLBACK(iupgtkEnterLeaveEvent), ih);
+  g_signal_connect(G_OBJECT(ih->handle), "focus-in-event",      G_CALLBACK(iupgtkFocusInOutEvent), ih);
+  g_signal_connect(G_OBJECT(ih->handle), "focus-out-event",     G_CALLBACK(iupgtkFocusInOutEvent), ih);
+  g_signal_connect(G_OBJECT(ih->handle), "key-press-event",     G_CALLBACK(iupgtkKeyPressEvent),   ih);
+  g_signal_connect(G_OBJECT(ih->handle), "show-help",           G_CALLBACK(iupgtkShowHelp),        ih);
+
+  g_signal_connect(G_OBJECT(ih->handle), "switch-page",         G_CALLBACK(gtkTabSwitchPage), ih);
+
+  gtk_widget_realize(ih->handle);
+  */
+
+  /* Create pages and tabs */
+  if (ih->firstchild)
+  {
+    Ihandle* child;
+    for (child = ih->firstchild; child; child = child->brother)
+      haikuTabsChildAddedMethod(ih, child);
+  }
+
+  return IUP_NOERROR;
+}
+
+void iupdrvTabsInitClass(Iclass* ic)
+{
+  /* Driver Dependent Class functions */
+  ic->Map = haikuTabsMapMethod;
+  ic->ChildAdded     = haikuTabsChildAddedMethod;
+  ic->ChildRemoved   = gtkTabsChildRemovedMethod;
+
+  /* Driver Dependent Attribute functions */
+
+  /* Common */
+  iupClassRegisterAttribute(ic, "STANDARDFONT", NULL, gtkTabsSetStandardFontAttrib,
+	IUPAF_SAMEASSYSTEM, "DEFAULTFONT", IUPAF_NO_SAVE|IUPAF_NOT_MAPPED);
+
+  /* Visual */
+  iupClassRegisterAttribute(ic, "BGCOLOR", NULL, gtkTabsSetBgColorAttrib,
+	IUPAF_SAMEASSYSTEM, "DLGBGCOLOR", IUPAF_DEFAULT);
+  iupClassRegisterAttribute(ic, "FGCOLOR", NULL, gtkTabsSetFgColorAttrib,
+	IUPAF_SAMEASSYSTEM, "DLGFGCOLOR", IUPAF_DEFAULT);
+
+  /* IupTabs only */
+  iupClassRegisterAttribute(ic, "TABTYPE", iupTabsGetTabTypeAttrib,
+	gtkTabsSetTabTypeAttrib, IUPAF_SAMEASSYSTEM, "TOP", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT);
+  iupClassRegisterAttribute(ic, "TABORIENTATION", iupTabsGetTabOrientationAttrib,
+	gtkTabsSetTabOrientationAttrib, IUPAF_SAMEASSYSTEM, "HORIZONTAL",
+	IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT);
+  iupClassRegisterAttributeId(ic, "TABTITLE", NULL, haikuTabsSetTabTitleAttrib,
+	IUPAF_NO_INHERIT);
+  iupClassRegisterAttributeId(ic, "TABIMAGE", NULL, gtkTabsSetTabImageAttrib,
+	IUPAF_IHANDLENAME|IUPAF_NO_INHERIT);
+  iupClassRegisterAttribute(ic, "PADDING", iupTabsGetPaddingAttrib,
+	gtkTabsSetPaddingAttrib, IUPAF_SAMEASSYSTEM, "0x0", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT);
+
+  /* NOT supported */
+  iupClassRegisterAttribute(ic, "MULTILINE", NULL, NULL, NULL, NULL,
+	IUPAF_NOT_SUPPORTED|IUPAF_DEFAULT);
+}
diff --git a/src/haiku/iuphaiku_text.cpp b/src/haiku/iuphaiku_text.cpp
new file mode 100644
index 0000000..1afd172
--- /dev/null
+++ b/src/haiku/iuphaiku_text.cpp
@@ -0,0 +1,394 @@
+/** \file
+ * \brief Text Control
+ *
+ * See Copyright Notice in "iup.h"
+ */
+
+#define UNIMPLEMENTED printf("%s (%s %d) UNIMPLEMENTED\n",__func__,__FILE__,__LINE__);
+
+#include <TextControl.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <memory.h>
+#include <stdarg.h>
+
+#include "iup.h"
+#include "iupcbs.h"
+
+#include "iup_object.h"
+#include "iup_layout.h"
+#include "iup_attrib.h"
+#include "iup_str.h"
+#include "iup_image.h"
+#include "iup_mask.h"
+#include "iup_drv.h"
+#include "iup_drvfont.h"
+#include "iup_image.h"
+#include "iup_key.h"
+#include "iup_array.h"
+#include "iup_text.h"
+
+#include "iuphaiku_drv.h"
+
+#ifndef PANGO_WEIGHT_SEMIBOLD
+#define PANGO_WEIGHT_SEMIBOLD 600
+#endif
+
+void iupdrvTextAddSpin(int *w, int h)
+{
+  int spin_size = 16;
+  *w += spin_size;
+  (void)h;
+}
+
+void iupdrvTextAddBorders(int *x, int *y)
+{
+  int border_size = 2*5;
+  (*x) += border_size;
+  (*y) += border_size;
+}
+
+void iupdrvTextConvertLinColToPos(Ihandle* ih, int lin, int col, int *pos)
+{
+	UNIMPLEMENTED
+}
+
+void iupdrvTextConvertPosToLinCol(Ihandle* ih, int pos, int *lin, int *col)
+{
+	UNIMPLEMENTED
+}
+
+/*******************************************************************************************/
+
+
+static int gtkTextSetSelectionAttrib(Ihandle* ih, const char* value)
+{
+	UNIMPLEMENTED
+  return 0;
+}
+
+static char* gtkTextGetSelectionAttrib(Ihandle* ih)
+{
+	UNIMPLEMENTED
+  return NULL;
+}
+
+static int gtkTextSetSelectionPosAttrib(Ihandle* ih, const char* value)
+{
+	UNIMPLEMENTED
+  return 0;
+}
+
+static char* gtkTextGetSelectionPosAttrib(Ihandle* ih)
+{
+	UNIMPLEMENTED
+  return NULL;
+}
+
+static int gtkTextSetSelectedTextAttrib(Ihandle* ih, const char* value)
+{
+	UNIMPLEMENTED
+  return 0;
+}
+
+static char* gtkTextGetCountAttrib(Ihandle* ih)
+{
+	UNIMPLEMENTED
+  return NULL;
+}
+
+static char* gtkTextGetLineCountAttrib(Ihandle* ih)
+{
+	UNIMPLEMENTED
+  return NULL;
+}
+
+static char* gtkTextGetSelectedTextAttrib(Ihandle* ih)
+{
+	UNIMPLEMENTED
+  return NULL;
+}
+
+static int gtkTextSetCaretAttrib(Ihandle* ih, const char* value)
+{
+	UNIMPLEMENTED
+  return 0;
+}
+
+static char* gtkTextGetCaretAttrib(Ihandle* ih)
+{
+	UNIMPLEMENTED
+  return NULL;
+}
+
+static int gtkTextSetCaretPosAttrib(Ihandle* ih, const char* value)
+{
+	UNIMPLEMENTED
+  return 0;
+}
+
+static char* gtkTextGetCaretPosAttrib(Ihandle* ih)
+{
+	UNIMPLEMENTED
+  return NULL;
+}
+
+static int gtkTextSetScrollToAttrib(Ihandle* ih, const char* value)
+{
+	UNIMPLEMENTED
+  return 0;
+}
+
+static int gtkTextSetScrollToPosAttrib(Ihandle* ih, const char* value)
+{
+	UNIMPLEMENTED
+  return 0;
+}
+
+static int gtkTextSetValueAttrib(Ihandle* ih, const char* value)
+{
+  BView* view = (BView*)ih->handle;
+
+  BTextControl* ctrl = dynamic_cast<BTextControl*>(view);
+  if (ctrl) {
+	ctrl->SetText(value);
+  } else
+	UNIMPLEMENTED
+  return 0;
+}
+
+static char* gtkTextGetValueAttrib(Ihandle* ih)
+{
+	UNIMPLEMENTED
+  return NULL;
+}
+                       
+static char* gtkTextGetLineValueAttrib(Ihandle* ih)
+{
+	UNIMPLEMENTED
+  return NULL;
+}
+
+static int gtkTextSetInsertAttrib(Ihandle* ih, const char* value)
+{
+	UNIMPLEMENTED
+  return 0;
+}
+
+static int gtkTextSetAppendAttrib(Ihandle* ih, const char* value)
+{
+	UNIMPLEMENTED
+  return 0;
+}
+
+static int gtkTextSetAlignmentAttrib(Ihandle* ih, const char* value)
+{
+	UNIMPLEMENTED
+  return 1;
+}
+
+static int gtkTextSetPaddingAttrib(Ihandle* ih, const char* value)
+{
+	UNIMPLEMENTED
+    return 1; /* store until not mapped, when mapped will be set again */
+}
+
+static int gtkTextSetNCAttrib(Ihandle* ih, const char* value)
+{
+	UNIMPLEMENTED
+    return 1; /* store until not mapped, when mapped will be set again */
+}
+
+static int gtkTextSetClipboardAttrib(Ihandle *ih, const char *value)
+{
+	UNIMPLEMENTED
+  return 0;
+}
+
+static int gtkTextSetReadOnlyAttrib(Ihandle* ih, const char* value)
+{
+	UNIMPLEMENTED
+  return 0;
+}
+
+static char* gtkTextGetReadOnlyAttrib(Ihandle* ih)
+{
+	UNIMPLEMENTED
+  return NULL;
+}
+
+static char* gtkTextGetWidgetPangoLayoutAttrib(Ihandle* ih)
+{
+  if (ih->data->is_multiline)
+    return NULL;
+  else
+	UNIMPLEMENTED
+  return NULL;
+}
+
+static int gtkTextSetBgColorAttrib(Ihandle* ih, const char* value)
+{
+	UNIMPLEMENTED
+		return 0;
+}
+
+static int gtkTextSetTabSizeAttrib(Ihandle* ih, const char* value)
+{
+	UNIMPLEMENTED
+  return 1;
+}
+
+static int gtkTextSetOverwriteAttrib(Ihandle* ih, const char* value)
+{
+  if (!ih->data->is_multiline)
+    return 0;
+	UNIMPLEMENTED
+  return 0;
+}
+
+static char* gtkTextGetOverwriteAttrib(Ihandle* ih)
+{
+  if (!ih->data->is_multiline)
+    return "NO";
+	UNIMPLEMENTED
+	return NULL;
+}
+
+void* iupdrvTextAddFormatTagStartBulk(Ihandle* ih)
+{
+	UNIMPLEMENTED
+  return NULL;
+}
+
+void iupdrvTextAddFormatTagStopBulk(Ihandle* ih, void* state)
+{
+	UNIMPLEMENTED
+}
+
+void iupdrvTextAddFormatTag(Ihandle* ih, Ihandle* formattag, int bulk)
+{
+	UNIMPLEMENTED
+}
+
+static int gtkTextSetRemoveFormattingAttrib(Ihandle* ih, const char* value)
+{
+	UNIMPLEMENTED
+  return 0;
+}
+
+
+static int gtkTextSetSpinMinAttrib(Ihandle* ih, const char* value)
+{
+	UNIMPLEMENTED
+  return 1;
+}
+
+static int gtkTextSetSpinMaxAttrib(Ihandle* ih, const char* value)
+{
+	UNIMPLEMENTED
+  return 1;
+}
+
+static int gtkTextSetSpinIncAttrib(Ihandle* ih, const char* value)
+{
+	UNIMPLEMENTED
+  return 1;
+}
+
+static int gtkTextSetSpinValueAttrib(Ihandle* ih, const char* value)
+{
+	UNIMPLEMENTED
+  return 1;
+}
+
+static char* gtkTextGetSpinValueAttrib(Ihandle* ih)
+{
+	UNIMPLEMENTED
+  return NULL;
+}
+
+
+/**********************************************************************************************************/
+
+
+static int gtkTextMapMethod(Ihandle* ih)
+{
+  static const BRect defaultRect(0, 0, 10, 10);
+  if (ih->data->is_multiline) {
+	ih->handle = (InativeHandle*)new BTextView(defaultRect, "multiline",
+	  defaultRect, B_FOLLOW_ALL_SIDES, B_WILL_DRAW);
+  } else if (iupAttribGetBoolean(ih, "SPIN")) {
+	UNIMPLEMENTED
+	// TODO build an actual spinner control !
+	ih->handle = (InativeHandle*)new BTextControl(defaultRect, "text",
+	  NULL, NULL, NULL);
+  } else {
+	ih->handle = (InativeHandle*)new BTextControl(defaultRect, "text",
+	  NULL, NULL, NULL);
+    if (iupAttribGetBoolean(ih, "PASSWORD"))
+	  UNIMPLEMENTED
+  }
+
+  iuphaikuBaseAddToParent(ih);
+
+  if (!iupAttribGetBoolean(ih, "CANFOCUS"))
+	UNIMPLEMENTED
+  
+  return IUP_NOERROR;
+}
+
+void iupdrvTextInitClass(Iclass* ic)
+{
+  /* Driver Dependent Class functions */
+  ic->Map = gtkTextMapMethod;
+
+  /* Driver Dependent Attribute functions */
+
+  /* Common GTK only (when text is in a secondary element) */
+  iupClassRegisterAttribute(ic, "WIDGETPANGOLAYOUT", gtkTextGetWidgetPangoLayoutAttrib, NULL, NULL, NULL, IUPAF_NO_INHERIT);
+
+  /* Visual */
+  iupClassRegisterAttribute(ic, "BGCOLOR", NULL, gtkTextSetBgColorAttrib, IUPAF_SAMEASSYSTEM, "TXTBGCOLOR", IUPAF_DEFAULT);
+
+  /* Special */
+  iupClassRegisterAttribute(ic, "FGCOLOR", NULL, iupdrvBaseSetFgColorAttrib, IUPAF_SAMEASSYSTEM, "TXTFGCOLOR", IUPAF_DEFAULT);
+
+  /* IupText only */
+  iupClassRegisterAttribute(ic, "PADDING", iupTextGetPaddingAttrib, gtkTextSetPaddingAttrib, IUPAF_SAMEASSYSTEM, "0x0", IUPAF_NOT_MAPPED);
+  iupClassRegisterAttribute(ic, "VALUE", gtkTextGetValueAttrib, gtkTextSetValueAttrib, NULL, NULL, IUPAF_NO_DEFAULTVALUE|IUPAF_NO_INHERIT);
+  iupClassRegisterAttribute(ic, "LINEVALUE", gtkTextGetLineValueAttrib, NULL, NULL, NULL, IUPAF_READONLY|IUPAF_NO_DEFAULTVALUE|IUPAF_NO_INHERIT);
+  iupClassRegisterAttribute(ic, "SELECTEDTEXT", gtkTextGetSelectedTextAttrib, gtkTextSetSelectedTextAttrib, NULL, NULL, IUPAF_NO_INHERIT);
+  iupClassRegisterAttribute(ic, "SELECTION", gtkTextGetSelectionAttrib, gtkTextSetSelectionAttrib, NULL, NULL, IUPAF_NO_INHERIT);
+  iupClassRegisterAttribute(ic, "SELECTIONPOS", gtkTextGetSelectionPosAttrib, gtkTextSetSelectionPosAttrib, NULL, NULL, IUPAF_NO_INHERIT);
+  iupClassRegisterAttribute(ic, "CARET", gtkTextGetCaretAttrib, gtkTextSetCaretAttrib, NULL, NULL, IUPAF_NO_SAVE|IUPAF_NO_INHERIT);
+  iupClassRegisterAttribute(ic, "CARETPOS", gtkTextGetCaretPosAttrib, gtkTextSetCaretPosAttrib, IUPAF_SAMEASSYSTEM, "0", IUPAF_NO_SAVE|IUPAF_NO_INHERIT);
+  iupClassRegisterAttribute(ic, "INSERT", NULL, gtkTextSetInsertAttrib, NULL, NULL, IUPAF_NOT_MAPPED|IUPAF_WRITEONLY|IUPAF_NO_INHERIT);
+  iupClassRegisterAttribute(ic, "APPEND", NULL, gtkTextSetAppendAttrib, NULL, NULL, IUPAF_NOT_MAPPED|IUPAF_WRITEONLY|IUPAF_NO_INHERIT);
+  iupClassRegisterAttribute(ic, "READONLY", gtkTextGetReadOnlyAttrib, gtkTextSetReadOnlyAttrib, NULL, NULL, IUPAF_DEFAULT);
+  iupClassRegisterAttribute(ic, "NC", iupTextGetNCAttrib, gtkTextSetNCAttrib, IUPAF_SAMEASSYSTEM, "0", IUPAF_NOT_MAPPED);
+  iupClassRegisterAttribute(ic, "CLIPBOARD", NULL, gtkTextSetClipboardAttrib, NULL, NULL, IUPAF_NO_INHERIT);
+  iupClassRegisterAttribute(ic, "SCROLLTO", NULL, gtkTextSetScrollToAttrib, NULL, NULL, IUPAF_WRITEONLY|IUPAF_NO_INHERIT);
+  iupClassRegisterAttribute(ic, "SCROLLTOPOS", NULL, gtkTextSetScrollToPosAttrib, NULL, NULL, IUPAF_WRITEONLY|IUPAF_NO_INHERIT);
+  iupClassRegisterAttribute(ic, "SPINMIN", NULL, gtkTextSetSpinMinAttrib, IUPAF_SAMEASSYSTEM, "0", IUPAF_NO_INHERIT);
+  iupClassRegisterAttribute(ic, "SPINMAX", NULL, gtkTextSetSpinMaxAttrib, IUPAF_SAMEASSYSTEM, "100", IUPAF_NO_INHERIT);
+  iupClassRegisterAttribute(ic, "SPININC", NULL, gtkTextSetSpinIncAttrib, IUPAF_SAMEASSYSTEM, "1", IUPAF_NO_INHERIT);
+  iupClassRegisterAttribute(ic, "SPINVALUE", gtkTextGetSpinValueAttrib, gtkTextSetSpinValueAttrib, IUPAF_SAMEASSYSTEM, "0", IUPAF_NO_INHERIT);
+  iupClassRegisterAttribute(ic, "COUNT", gtkTextGetCountAttrib, NULL, NULL, NULL, IUPAF_READONLY|IUPAF_NO_INHERIT);
+  iupClassRegisterAttribute(ic, "LINECOUNT", gtkTextGetLineCountAttrib, NULL, NULL, NULL, IUPAF_READONLY|IUPAF_NO_INHERIT);
+
+  /* IupText Windows and GTK only */
+  iupClassRegisterAttribute(ic, "ADDFORMATTAG", NULL, iupTextSetAddFormatTagAttrib, NULL, NULL, IUPAF_IHANDLENAME|IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT);
+  iupClassRegisterAttribute(ic, "ADDFORMATTAG_HANDLE", NULL, iupTextSetAddFormatTagHandleAttrib, NULL, NULL, IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT);
+  iupClassRegisterAttribute(ic, "ALIGNMENT", NULL, gtkTextSetAlignmentAttrib, IUPAF_SAMEASSYSTEM, "ALEFT", IUPAF_NO_INHERIT);
+  iupClassRegisterAttribute(ic, "FORMATTING", iupTextGetFormattingAttrib, iupTextSetFormattingAttrib, NULL, NULL, IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT);
+  iupClassRegisterAttribute(ic, "OVERWRITE", gtkTextGetOverwriteAttrib, gtkTextSetOverwriteAttrib, NULL, NULL, IUPAF_NO_INHERIT);
+  iupClassRegisterAttribute(ic, "REMOVEFORMATTING", NULL, gtkTextSetRemoveFormattingAttrib, NULL, NULL, IUPAF_WRITEONLY|IUPAF_NO_INHERIT);
+  iupClassRegisterAttribute(ic, "TABSIZE", NULL, gtkTextSetTabSizeAttrib, "8", NULL, IUPAF_DEFAULT);  /* force new default value */
+  iupClassRegisterAttribute(ic, "PASSWORD", NULL, NULL, NULL, NULL, IUPAF_NO_INHERIT);
+
+  /* Not Supported */
+  iupClassRegisterAttribute(ic, "CUEBANNER", NULL, NULL, NULL, NULL, IUPAF_NOT_SUPPORTED|IUPAF_NO_INHERIT);
+  iupClassRegisterAttribute(ic, "FILTER", NULL, NULL, NULL, NULL, IUPAF_NOT_SUPPORTED|IUPAF_NO_INHERIT);
+}
diff --git a/src/haiku/iuphaiku_timer.cpp b/src/haiku/iuphaiku_timer.cpp
new file mode 100644
index 0000000..6839f1d
--- /dev/null
+++ b/src/haiku/iuphaiku_timer.cpp
@@ -0,0 +1,79 @@
+/** \file
+ * \brief Timer for the GTK Driver.
+ *
+ * See Copyright Notice in "iup.h"
+ */
+
+#include <Application.h>
+#include <Message.h>
+#include <MessageRunner.h>
+#include <Window.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "iup.h"
+
+#include "iup_object.h"
+#include "iup_attrib.h"
+#include "iup_str.h"
+#include "iup_assert.h"
+#include "iup_timer.h"
+
+#include "iuphaiku_drv.h"
+
+
+void iuphaikuTimerFired(Ihandle* ih)
+{
+  Icallback cb;
+
+  if (!iupObjectCheck(ih)) {
+	/* control was destroyed before timer callback */
+    return;
+  }
+
+  cb = IupGetCallback(ih, "ACTION_CB");
+  if (cb && cb(ih)==IUP_CLOSE)
+    IupExitLoop();
+}
+
+void iupdrvTimerRun(Ihandle *ih)
+{
+  unsigned int time_ms;
+
+  if (ih->serial > 0) /* timer already started */
+    return;
+  
+  time_ms = iupAttribGetInt(ih, "TIME");
+  if (time_ms > 0) {
+	BMessage* msg = new BMessage(timerFire);
+	msg->AddPointer("iHandle", ih);
+
+    BLooper* looper = be_app->WindowAt(be_app->CountWindows() - 1);
+	if (looper == NULL) {
+		looper = be_app;
+	}
+
+    BMessenger messenger(looper);
+
+	ih->handle = (InativeHandle*)new BMessageRunner(messenger, msg, time_ms * 1000);
+	// Just use something "reasonably unique" as the serial...
+	ih->serial = (int)ih->handle;
+	if (ih->serial < 0) ih->serial = -ih->serial;
+  }
+}
+
+void iupdrvTimerStop(Ihandle* ih)
+{
+  if (ih->serial > 0)
+  {
+	BMessageRunner* runner = (BMessageRunner*)ih->handle;
+	delete runner;
+    ih->serial = -1;
+  }
+}
+
+void iupdrvTimerInitClass(Iclass* ic)
+{
+  (void)ic;
+}
diff --git a/src/haiku/iuphaiku_tips.c b/src/haiku/iuphaiku_tips.c
new file mode 100644
index 0000000..de57538
--- /dev/null
+++ b/src/haiku/iuphaiku_tips.c
@@ -0,0 +1,39 @@
+/** \file
+ * \brief Windows Driver TIPS management
+ *
+ * See Copyright Notice in "iup.h"
+ */
+
+#include <stdio.h>
+
+#include "iup.h" 
+#include "iupcbs.h" 
+
+#include "iup_object.h" 
+#include "iup_str.h" 
+#include "iup_attrib.h" 
+#include "iup_image.h" 
+#include "iup_drv.h"
+#include "iup_drvinfo.h"
+
+#include "iuphaiku_drv.h"
+#define UNIMPLEMENTED printf("%s (%s %d) UNIMPLEMENTED\n",__func__,__FILE__,__LINE__);
+
+int iupdrvBaseSetTipAttrib(Ihandle* ih, const char* value)
+{
+	// FIXME Haiku has no official support for tooltips (there's an internal API)
+	UNIMPLEMENTED
+  return 1;
+}
+
+int iupdrvBaseSetTipVisibleAttrib(Ihandle* ih, const char* value)
+{
+	UNIMPLEMENTED
+  return 0;
+}
+
+char* iupdrvBaseGetTipVisibleAttrib(Ihandle* ih)
+{
+	UNIMPLEMENTED
+  return NULL;
+}
diff --git a/src/haiku/iuphaiku_toggle.cpp b/src/haiku/iuphaiku_toggle.cpp
new file mode 100644
index 0000000..a4fc50e
--- /dev/null
+++ b/src/haiku/iuphaiku_toggle.cpp
@@ -0,0 +1,298 @@
+/** \file
+ * \brief Toggle Control
+ *
+ * See Copyright Notice in "iup.h"
+ */
+
+#define UNIMPLEMENTED printf("%s (%s %d) UNIMPLEMENTED\n",__func__,__FILE__,__LINE__);
+
+#include <CheckBox.h>
+#include <PictureButton.h>
+#include <RadioButton.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <memory.h>
+#include <stdarg.h>
+
+#include "iup.h"
+#include "iupcbs.h"
+
+#include "iup_object.h"
+#include "iup_layout.h"
+#include "iup_attrib.h"
+#include "iup_str.h"
+#include "iup_image.h"
+#include "iup_drv.h"
+#include "iup_drvfont.h"
+#include "iup_image.h"
+#include "iup_key.h"
+#include "iup_toggle.h"
+
+#include "iuphaiku_drv.h"
+
+
+void iupdrvToggleAddCheckBox(int *x, int *y)
+{
+#ifdef HILDON
+  (*x) += 30+4;
+  if ((*y) < 30) (*y) = 30; /* minimum height */
+#else
+  (*x) += 16+4;
+  if ((*y) < 16) (*y) = 16; /* minimum height */
+#endif
+  (*y) += 4;
+}
+
+static int beToggleGetCheck(Ihandle* ih)
+{
+	BControl* control = (BControl*)ih->handle;
+    return control->Value();
+}
+
+static BPicture* getPicture(Ihandle* ih, const char* name, int make_inactive, bool make_enabled = false)
+{
+  BPictureButton* button = (BPictureButton*)ih->handle;
+
+  if (name)
+  {
+	BBitmap* bitmap = (BBitmap*)iupImageGetImage(name, ih, make_inactive);
+	BPicture* picture = new BPicture();
+	button->LockLooper();
+
+	button->BeginPicture(picture);
+
+	// TODO use control look classes to draw a proper button border instead
+	if(make_enabled) {
+	  button->SetHighColor(ui_color(B_PANEL_TEXT_COLOR));
+	  button->StrokeRect(button->Bounds());
+	}
+
+	button->DrawBitmapAsync(bitmap);
+
+	button->EndPicture();
+
+	button->UnlockLooper();
+
+	return picture;
+  }
+
+  return NULL;
+}
+
+static void beToggleUpdateImage(Ihandle* ih, int active, int check)
+{
+  char* name;
+  BPicture* pic;
+  BPictureButton* button = (BPictureButton*)ih->handle;
+
+  pic = getPicture(ih, iupAttribGet(ih, "IMAGE"), 0);
+  button->SetEnabledOff(pic);
+
+  name = iupAttribGet(ih, "IMINACTIVE");
+  if (name)
+  	pic = getPicture(ih, name, 0);
+  else
+    pic = getPicture(ih, iupAttribGet(ih, "IMAGE"), 1);
+  button->SetDisabledOff(pic);
+  button->SetDisabledOn(pic);
+
+  name = iupAttribGet(ih, "IMPRESS");
+  if (name)
+  	pic = getPicture(ih, name, 0);
+  else
+    pic = getPicture(ih, iupAttribGet(ih, "IMAGE"), 0, true);
+  button->SetEnabledOn(pic);
+}
+
+
+/*************************************************************************/
+
+
+static int gtkToggleSetValueAttrib(Ihandle* ih, const char* value)
+{
+  if (iupStrEqualNoCase(value,"NOTDEF"))
+	UNIMPLEMENTED
+  else 
+  {
+	int check;
+    BControl* checkbox = (BCheckBox*)ih->handle;
+
+    if (iupStrEqualNoCase(value,"TOGGLE")) {
+	  check = checkbox->Value();
+	  if (check == 0) check = 1;
+	  else check = 0;
+	} else
+      check = iupStrBoolean(value);
+
+	checkbox->SetValue(check);
+  }
+
+  return 0;
+}
+
+static char* gtkToggleGetValueAttrib(Ihandle* ih)
+{
+  int check = beToggleGetCheck(ih);
+  if (check == -1)
+    return "NOTDEF";
+  else if (check == 1)
+    return "ON";
+  else
+    return "OFF";
+}
+
+static int beToggleSetTitleAttrib(Ihandle* ih, const char* value)
+{
+  BControl* checkbox = (BCheckBox*)ih->handle;
+  checkbox->SetLabel(value);
+  return 1;
+}
+
+static int gtkToggleSetAlignmentAttrib(Ihandle* ih, const char* value)
+{
+	UNIMPLEMENTED
+  return 1;
+}
+
+static int gtkToggleSetPaddingAttrib(Ihandle* ih, const char* value)
+{
+	UNIMPLEMENTED
+    return 1; /* store until not mapped, when mapped will be set again */
+}
+
+static int gtkToggleSetFgColorAttrib(Ihandle* ih, const char* value)
+{
+	UNIMPLEMENTED
+  return 1;
+}
+
+/*
+static int gtkToggleSetStandardFontAttrib(Ihandle* ih, const char* value)
+{
+	UNIMPLEMENTED
+  return 1;
+}
+*/
+
+static int beToggleSetImageAttrib(Ihandle* ih, const char* value)
+{
+  if (ih->data->type == IUP_TOGGLE_IMAGE)
+  {
+    if (value != iupAttribGet(ih, "IMAGE"))
+      iupAttribSetStr(ih, "IMAGE", (char*)value);
+    beToggleUpdateImage(ih, iupdrvIsActive(ih), beToggleGetCheck(ih));
+    return 1;
+  }
+  else
+    return 0;
+}
+
+static int beToggleSetImInactiveAttrib(Ihandle* ih, const char* value)
+{
+  if (ih->data->type == IUP_TOGGLE_IMAGE)
+  {
+    if (value != iupAttribGet(ih, "IMINACTIVE"))
+      iupAttribSetStr(ih, "IMINACTIVE", (char*)value);
+    beToggleUpdateImage(ih, iupdrvIsActive(ih), beToggleGetCheck(ih));
+    return 1;
+  }
+  else
+    return 0;
+}
+
+static int gtkToggleSetImPressAttrib(Ihandle* ih, const char* value)
+{
+  if (ih->data->type == IUP_TOGGLE_IMAGE)
+  {
+    if (value != iupAttribGet(ih, "IMPRESS"))
+      iupAttribSetStr(ih, "IMPRESS", (char*)value);
+    beToggleUpdateImage(ih, iupdrvIsActive(ih), beToggleGetCheck(ih));
+    return 1;
+  }
+  else
+    return 0;
+}
+
+// Event handlers
+
+void iuphaikuToggleInvoked(Ihandle* ih, int value)
+{
+  IFni cb = (IFni) IupGetCallback(ih, "ACTION");
+  if (cb && cb(ih, value) == IUP_CLOSE)
+    IupExitLoop();
+
+  if (iupObjectCheck(ih))
+    iupBaseCallValueChangedCb(ih);
+}
+
+/****************************************************************************************************/
+
+static int gtkToggleMapMethod(Ihandle* ih)
+{
+  Ihandle* radio = iupRadioFindToggleParent(ih);
+
+  if (radio)
+    ih->data->radio = 1;
+  
+  char* value = iupAttribGet(ih, "IMAGE");
+  if (value)
+  {
+    ih->data->type = IUP_TOGGLE_IMAGE;
+	// The pictures will be set only later, from the image callbacks.
+	BPicture* empty = new BPicture();
+	ih->handle = (InativeHandle*)new BPictureButton(BRect(0,0,10,10), "PictureButton", empty, empty, NULL,
+	  B_TWO_STATE_BUTTON);
+	delete empty;
+  }
+  else
+  {
+    ih->data->type = IUP_TOGGLE_TEXT;
+
+    if (radio) {
+      ih->handle = (InativeHandle*)new BRadioButton(BRect(0,0,10,10), "Radio", NULL, NULL);
+    } else {
+      ih->handle = (InativeHandle*)new BCheckBox(BRect(0,0,10,10), "Checkbox", NULL, NULL);
+    }
+  }
+
+  BControl* ctrl = (BControl*)(ih->handle);
+  BMessage* message = new BMessage(checkboxInvoke);
+  message->AddPointer("iHandle", ih);
+  ctrl->SetMessage(message);
+
+  iuphaikuBaseAddToParent(ih);
+  return IUP_NOERROR;
+}
+
+void iupdrvToggleInitClass(Iclass* ic)
+{
+  /* Driver Dependent Class functions */
+  ic->Map = gtkToggleMapMethod;
+
+  /* Driver Dependent Attribute functions */
+
+  /* Overwrite Common */
+  //iupClassRegisterAttribute(ic, "STANDARDFONT", NULL, gtkToggleSetStandardFontAttrib, IUPAF_SAMEASSYSTEM, "DEFAULTFONT", IUPAF_NO_SAVE|IUPAF_NOT_MAPPED);
+
+  /* Visual */
+  iupClassRegisterAttribute(ic, "BGCOLOR", NULL, iupdrvBaseSetBgColorAttrib, IUPAF_SAMEASSYSTEM, "DLGBGCOLOR", IUPAF_DEFAULT);
+
+  /* Special */
+  iupClassRegisterAttribute(ic, "FGCOLOR", NULL, gtkToggleSetFgColorAttrib, IUPAF_SAMEASSYSTEM, "DLGFGCOLOR", IUPAF_DEFAULT);  /* black */
+  iupClassRegisterAttribute(ic, "TITLE", NULL, beToggleSetTitleAttrib, NULL, NULL, IUPAF_NO_DEFAULTVALUE|IUPAF_NO_INHERIT);
+
+  /* IupToggle only */
+  iupClassRegisterAttribute(ic, "ALIGNMENT", NULL, gtkToggleSetAlignmentAttrib, "ACENTER:ACENTER", NULL, IUPAF_NO_INHERIT); /* force new default value */
+  iupClassRegisterAttribute(ic, "IMAGE", NULL, beToggleSetImageAttrib, NULL, NULL, IUPAF_IHANDLENAME|IUPAF_NO_DEFAULTVALUE|IUPAF_NO_INHERIT);
+  iupClassRegisterAttribute(ic, "IMINACTIVE", NULL, beToggleSetImInactiveAttrib, NULL, NULL, IUPAF_IHANDLENAME|IUPAF_NO_DEFAULTVALUE|IUPAF_NO_INHERIT);
+  iupClassRegisterAttribute(ic, "IMPRESS", NULL, gtkToggleSetImPressAttrib, NULL, NULL, IUPAF_IHANDLENAME|IUPAF_NO_DEFAULTVALUE|IUPAF_NO_INHERIT);
+  iupClassRegisterAttribute(ic, "VALUE", gtkToggleGetValueAttrib, gtkToggleSetValueAttrib, NULL, NULL, IUPAF_NO_DEFAULTVALUE|IUPAF_NO_INHERIT);
+
+  iupClassRegisterAttribute(ic, "PADDING", iupToggleGetPaddingAttrib, gtkToggleSetPaddingAttrib, IUPAF_SAMEASSYSTEM, "0x0", IUPAF_NOT_MAPPED);
+  iupClassRegisterAttribute(ic, "MARKUP", NULL, NULL, NULL, NULL, IUPAF_DEFAULT);
+
+  /* NOT supported */
+  iupClassRegisterAttribute(ic, "RIGHTBUTTON", NULL, NULL, NULL, NULL, IUPAF_NOT_SUPPORTED|IUPAF_DEFAULT);
+}
diff --git a/src/haiku/iuphaiku_tree.cpp b/src/haiku/iuphaiku_tree.cpp
new file mode 100644
index 0000000..46520d1
--- /dev/null
+++ b/src/haiku/iuphaiku_tree.cpp
@@ -0,0 +1,482 @@
+/** \file
+ * \brief Tree Control
+ *
+ * See Copyright Notice in iup.h
+ */
+
+#define UNIMPLEMENTED printf("%s (%s %d) UNIMPLEMENTED\n",__func__,__FILE__,__LINE__);
+
+#include <OutlineListView.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <memory.h>
+#include <stdarg.h>
+
+#include "iup.h"
+#include "iupcbs.h"
+
+#include "iup_object.h"
+#include "iup_layout.h"
+#include "iup_attrib.h"
+#include "iup_str.h"
+#include "iup_drv.h"
+#include "iup_drvfont.h"
+#include "iup_stdcontrols.h"
+#include "iup_key.h"
+#include "iup_image.h"
+#include "iup_array.h"
+#include "iup_tree.h"
+
+#include "iup_drvinfo.h"
+#include "iuphaiku_drv.h"
+
+
+class IUPListItem: public BStringItem
+{
+	public:
+		IUPListItem(const char* title, int level)
+			: BStringItem(title, level)
+		{}
+
+		int kind;
+};
+
+
+/*****************************************************************************/
+/* MANIPULATING IMAGES                                                       */
+/*****************************************************************************/
+static void gtkTreeUpdateImages(Ihandle* ih, int mode)
+{
+	UNIMPLEMENTED
+}
+
+/*****************************************************************************/
+/* ADDING ITEMS                                                              */
+/*****************************************************************************/
+void iupdrvTreeAddNode(Ihandle* ih, int id, int kind, const char* title, int add)
+{
+  BOutlineListView* list = (BOutlineListView*)ih->handle;
+  int kindPrev = -1;
+  int level = 0;
+
+  IUPListItem* parent = (IUPListItem*)list->FullListItemAt(id);
+
+  // Only the root node is allowed to have no parent
+  if(parent == NULL && id != -1)
+	return;
+  else if(parent) {
+    kindPrev = parent->kind;
+  }
+
+  if (kindPrev != -1)
+  { 
+    level = parent->OutlineLevel();
+    // The parent has a valid kind
+    if (kindPrev == ITREE_BRANCH && add)
+	  level++; // Adding item inside the branch
+    else
+	  id += list->CountItemsUnder(parent, true); // Adding item as a sibling of 'parent'
+  }
+    
+  IUPListItem* item = new IUPListItem(title, level);
+  item->kind = kind;
+
+  bool unlock = list->LockLooper();
+  	// No need to lock if the list is currently unmapped (happens when it was
+	// added to a BTabView, but that one is hidden)
+  list->AddItem(item, id + 1);
+  if (unlock) list->UnlockLooper();
+
+  // TODO FGCOLOR, default images, ADDEXPANDED
+}
+
+
+/*****************************************************************************/
+/* AUXILIAR FUNCTIONS                                                        */
+/*****************************************************************************/
+
+
+int iupdrvTreeTotalChildCount(Ihandle* ih, InodeHandle* node_handle)
+{
+  int count = 0;
+  UNIMPLEMENTED
+  return count;
+}
+
+InodeHandle* iupdrvTreeGetFocusNode(Ihandle* ih)
+{
+	UNIMPLEMENTED
+  return NULL;
+}
+
+typedef struct _gtkTreeSelectMinMax
+{
+  Ihandle* ih;
+  int id1, id2;
+} gtkTreeSelectMinMax;
+
+/*****************************************************************************/
+/* GET AND SET ATTRIBUTES                                                    */
+/*****************************************************************************/
+
+
+static char* gtkTreeGetIndentationAttrib(Ihandle* ih)
+{
+	UNIMPLEMENTED
+		return NULL;
+}
+
+static int gtkTreeSetIndentationAttrib(Ihandle* ih, const char* value)
+{
+	UNIMPLEMENTED
+  return 0;
+}
+
+static int gtkTreeSetTopItemAttrib(Ihandle* ih, const char* value)
+{
+	UNIMPLEMENTED
+  return 0;
+}
+
+static int gtkTreeSetSpacingAttrib(Ihandle* ih, const char* value)
+{
+	UNIMPLEMENTED
+    return 1; /* store until not mapped, when mapped will be set again */
+}
+
+static int gtkTreeSetExpandAllAttrib(Ihandle* ih, const char* value)
+{
+	UNIMPLEMENTED
+  return 0;
+}
+
+static char* gtkTreeGetDepthAttrib(Ihandle* ih, int id)
+{
+	UNIMPLEMENTED
+		return NULL;
+}
+
+static int gtkTreeSetMoveNodeAttrib(Ihandle* ih, int id, const char* value)
+{
+	UNIMPLEMENTED
+  return 0;
+}
+
+static int gtkTreeSetCopyNodeAttrib(Ihandle* ih, int id, const char* value)
+{
+	UNIMPLEMENTED
+  return 0;
+}
+
+static char* gtkTreeGetColorAttrib(Ihandle* ih, int id)
+{
+	UNIMPLEMENTED
+		return NULL;
+}
+
+static int gtkTreeSetColorAttrib(Ihandle* ih, int id, const char* value)
+{
+	UNIMPLEMENTED
+  return 0;
+}
+
+static char* gtkTreeGetParentAttrib(Ihandle* ih, int id)
+{
+	UNIMPLEMENTED
+		return NULL;
+}
+
+static char* gtkTreeGetChildCountAttrib(Ihandle* ih, int id)
+{
+	UNIMPLEMENTED
+		return NULL;
+}
+
+static char* gtkTreeGetKindAttrib(Ihandle* ih, int id)
+{
+	UNIMPLEMENTED
+		return NULL;
+}
+
+static char* gtkTreeGetStateAttrib(Ihandle* ih, int id)
+{
+	UNIMPLEMENTED
+  return NULL;
+}
+
+static int gtkTreeSetStateAttrib(Ihandle* ih, int id, const char* value)
+{
+	UNIMPLEMENTED
+  return 0;
+}
+
+static char* gtkTreeGetTitleAttrib(Ihandle* ih, int id)
+{
+	UNIMPLEMENTED
+    return NULL;
+}
+
+static int gtkTreeSetTitleAttrib(Ihandle* ih, int id, const char* value)
+{
+  BOutlineListView* lv = (BOutlineListView*)ih->handle;
+  BStringItem* item = (BStringItem*)lv->FullListItemAt(id);
+  item->SetText(value);
+  return 0;
+}
+
+static int gtkTreeSetTitleFontAttrib(Ihandle* ih, int id, const char* value)
+{
+	UNIMPLEMENTED
+  return 0;
+}
+
+static char* gtkTreeGetTitleFontAttrib(Ihandle* ih, int id)
+{
+	UNIMPLEMENTED
+    return NULL;
+}
+
+static char* gtkTreeGetValueAttrib(Ihandle* ih)
+{
+	UNIMPLEMENTED
+    return NULL;
+}
+
+static char* gtkTreeGetMarkedNodesAttrib(Ihandle* ih)
+{
+	UNIMPLEMENTED
+    return NULL;
+}
+
+static int gtkTreeSetMarkedNodesAttrib(Ihandle* ih, const char* value)
+{
+	UNIMPLEMENTED
+  return 0;
+}
+
+static int gtkTreeSetMarkAttrib(Ihandle* ih, const char* value)
+{
+	UNIMPLEMENTED
+  return 1;
+} 
+
+static int gtkTreeSetValueAttrib(Ihandle* ih, const char* value)
+{
+	UNIMPLEMENTED
+  return 0;
+} 
+
+static int gtkTreeSetMarkStartAttrib(Ihandle* ih, const char* value)
+{
+	UNIMPLEMENTED
+  return 1;
+}
+
+static char* gtkTreeGetMarkedAttrib(Ihandle* ih, int id)
+{
+	UNIMPLEMENTED
+    return NULL;
+}
+
+static int gtkTreeSetMarkedAttrib(Ihandle* ih, int id, const char* value)
+{
+	UNIMPLEMENTED
+  return 0;
+}
+
+static char* gtkTreeGetToggleValueAttrib(Ihandle* ih, int id)
+{
+	UNIMPLEMENTED
+    return NULL;
+}
+
+static int gtkTreeSetToggleValueAttrib(Ihandle* ih, int id, const char* value)
+{
+	UNIMPLEMENTED
+  return 0;
+}
+
+static int gtkTreeSetDelNodeAttrib(Ihandle* ih, int id, const char* value)
+{
+	UNIMPLEMENTED
+  return 0;
+}
+
+static int gtkTreeSetRenameAttrib(Ihandle* ih, const char* value)
+{  
+	UNIMPLEMENTED
+  return 0;
+}
+
+static int gtkTreeSetImageExpandedAttrib(Ihandle* ih, int id, const char* value)
+{
+	UNIMPLEMENTED
+  return 1;
+}
+
+static int gtkTreeSetImageAttrib(Ihandle* ih, int id, const char* value)
+{
+	UNIMPLEMENTED
+  return 0;
+}
+
+static int gtkTreeSetImageBranchExpandedAttrib(Ihandle* ih, const char* value)
+{
+  ih->data->def_image_expanded = iupImageGetImage(value, ih, 0);
+
+  /* Update all images */
+  gtkTreeUpdateImages(ih, ITREE_UPDATEIMAGE_EXPANDED);
+
+  return 1;
+}
+
+static int gtkTreeSetImageBranchCollapsedAttrib(Ihandle* ih, const char* value)
+{
+  ih->data->def_image_collapsed = iupImageGetImage(value, ih, 0);
+
+  /* Update all images */
+  gtkTreeUpdateImages(ih, ITREE_UPDATEIMAGE_COLLAPSED);
+
+  return 1;
+}
+
+static int gtkTreeSetImageLeafAttrib(Ihandle* ih, const char* value)
+{
+  ih->data->def_image_leaf = iupImageGetImage(value, ih, 0);
+
+  /* Update all images */
+  gtkTreeUpdateImages(ih, ITREE_UPDATEIMAGE_LEAF);
+
+  return 1;
+}
+
+static int gtkTreeSetBgColorAttrib(Ihandle* ih, const char* value)
+{
+	UNIMPLEMENTED
+  return 1;
+}
+
+static int gtkTreeSetFgColorAttrib(Ihandle* ih, const char* value)
+{
+	UNIMPLEMENTED
+  return 1;
+}
+
+static int gtkTreeSetShowRenameAttrib(Ihandle* ih, const char* value)
+{
+	UNIMPLEMENTED
+  return 0;
+}
+
+void iupdrvTreeUpdateMarkMode(Ihandle *ih)
+{
+  BListView* lv = (BListView*)ih->handle;
+  if(ih->data->mark_mode == ITREE_MARK_SINGLE)
+  {
+	lv->SetListType(B_SINGLE_SELECTION_LIST);
+  } else {
+	lv->SetListType(B_MULTIPLE_SELECTION_LIST);
+  }
+}
+
+
+/*****************************************************************************/
+
+static int haikuTreeMapMethod(Ihandle* ih)
+{
+  ih->handle = (InativeHandle*)new BOutlineListView(BRect(0, 0, 10, 10), "IUPOutline");
+
+  if(ih->data->show_toggle)
+	UNIMPLEMENTED
+  if (ih->data->show_rename)
+	UNIMPLEMENTED
+  if (ih->data->show_dragdrop)
+	UNIMPLEMENTED
+
+  iuphaikuBaseAddToParent(ih);
+
+  /*
+  if (!iupAttribGetBoolean(ih, "CANFOCUS"))
+    iuphaikuSetCanFocus(ih->handle, 0);
+  */
+
+  if (iupAttribGetInt(ih, "ADDROOT"))
+    iupdrvTreeAddNode(ih, -1, ITREE_BRANCH, "", 0);
+  
+  /* configure for DRAG&DROP of files */
+  if (IupGetCallback(ih, "DROPFILES_CB"))
+    iupAttribSetStr(ih, "DROPFILESTARGET", "YES");
+
+//  IupSetCallback(ih, "_IUP_XY2POS_CB", (Icallback)gtkTreeConvertXYToPos);
+  iupdrvTreeUpdateMarkMode(ih);
+
+  return IUP_NOERROR;
+}
+
+static void haikuTreeUnMapMethod(Ihandle* ih)
+{
+  ih->data->node_count = 0;
+
+  iupdrvBaseUnMapMethod(ih);
+}
+
+void iupdrvTreeInitClass(Iclass* ic)
+{
+  /* Driver Dependent Class functions */
+  ic->Map = haikuTreeMapMethod;
+  ic->UnMap = haikuTreeUnMapMethod;
+
+  /* Visual */
+  iupClassRegisterAttribute(ic, "BGCOLOR", NULL, gtkTreeSetBgColorAttrib, IUPAF_SAMEASSYSTEM, "TXTBGCOLOR", IUPAF_DEFAULT);
+  iupClassRegisterAttribute(ic, "FGCOLOR", NULL, gtkTreeSetFgColorAttrib, IUPAF_SAMEASSYSTEM, "TXTFGCOLOR", IUPAF_DEFAULT);
+
+  /* IupTree Attributes - GENERAL */
+  iupClassRegisterAttribute(ic, "EXPANDALL", NULL, gtkTreeSetExpandAllAttrib, NULL, NULL, IUPAF_WRITEONLY|IUPAF_NO_INHERIT);
+  iupClassRegisterAttribute(ic, "INDENTATION", gtkTreeGetIndentationAttrib, gtkTreeSetIndentationAttrib, NULL, NULL, IUPAF_DEFAULT);
+  iupClassRegisterAttribute(ic, "SPACING", iupTreeGetSpacingAttrib, gtkTreeSetSpacingAttrib, IUPAF_SAMEASSYSTEM, "0", IUPAF_NOT_MAPPED);
+  iupClassRegisterAttribute(ic, "TOPITEM", NULL, gtkTreeSetTopItemAttrib, NULL, NULL, IUPAF_WRITEONLY|IUPAF_NO_INHERIT);
+
+  /* IupTree Attributes - IMAGES */
+  iupClassRegisterAttributeId(ic, "IMAGE", NULL, gtkTreeSetImageAttrib, IUPAF_IHANDLENAME|IUPAF_WRITEONLY|IUPAF_NO_INHERIT);
+  iupClassRegisterAttributeId(ic, "IMAGEEXPANDED", NULL, gtkTreeSetImageExpandedAttrib, IUPAF_IHANDLENAME|IUPAF_WRITEONLY|IUPAF_NO_INHERIT);
+
+  iupClassRegisterAttribute(ic, "IMAGELEAF",            NULL, gtkTreeSetImageLeafAttrib, IUPAF_SAMEASSYSTEM, "IMGLEAF", IUPAF_IHANDLENAME|IUPAF_NO_INHERIT);
+  iupClassRegisterAttribute(ic, "IMAGEBRANCHCOLLAPSED", NULL, gtkTreeSetImageBranchCollapsedAttrib, IUPAF_SAMEASSYSTEM, "IMGCOLLAPSED", IUPAF_IHANDLENAME|IUPAF_NO_INHERIT);
+  iupClassRegisterAttribute(ic, "IMAGEBRANCHEXPANDED",  NULL, gtkTreeSetImageBranchExpandedAttrib, IUPAF_SAMEASSYSTEM, "IMGEXPANDED", IUPAF_IHANDLENAME|IUPAF_NO_INHERIT);
+
+  /* IupTree Attributes - NODES */
+  iupClassRegisterAttributeId(ic, "STATE",  gtkTreeGetStateAttrib,  gtkTreeSetStateAttrib, IUPAF_NO_INHERIT);
+  iupClassRegisterAttributeId(ic, "DEPTH",  gtkTreeGetDepthAttrib,  NULL, IUPAF_READONLY|IUPAF_NO_INHERIT);
+  iupClassRegisterAttributeId(ic, "KIND",   gtkTreeGetKindAttrib,   NULL, IUPAF_READONLY|IUPAF_NO_INHERIT);
+  iupClassRegisterAttributeId(ic, "PARENT", gtkTreeGetParentAttrib, NULL, IUPAF_READONLY|IUPAF_NO_INHERIT);
+  iupClassRegisterAttributeId(ic, "COLOR",  gtkTreeGetColorAttrib,  gtkTreeSetColorAttrib, IUPAF_NO_INHERIT);
+  iupClassRegisterAttributeId(ic, "NAME",   gtkTreeGetTitleAttrib,  gtkTreeSetTitleAttrib, IUPAF_NO_INHERIT);
+  iupClassRegisterAttributeId(ic, "TITLE",  gtkTreeGetTitleAttrib,  gtkTreeSetTitleAttrib, IUPAF_NO_INHERIT);
+  
+  /* Change the set method for GTK */
+  iupClassRegisterReplaceAttribFunc(ic, "SHOWRENAME", NULL, gtkTreeSetShowRenameAttrib);
+
+  iupClassRegisterAttributeId(ic, "CHILDCOUNT", gtkTreeGetChildCountAttrib, NULL, IUPAF_READONLY|IUPAF_NO_INHERIT);
+  iupClassRegisterAttributeId(ic, "TITLEFONT",  gtkTreeGetTitleFontAttrib,  gtkTreeSetTitleFontAttrib, IUPAF_NO_INHERIT);
+
+  /* IupTree Attributes - MARKS */
+  iupClassRegisterAttributeId(ic, "TOGGLEVALUE", gtkTreeGetToggleValueAttrib, gtkTreeSetToggleValueAttrib, IUPAF_NO_INHERIT);
+  iupClassRegisterAttributeId(ic, "MARKED", gtkTreeGetMarkedAttrib, gtkTreeSetMarkedAttrib, IUPAF_NO_DEFAULTVALUE|IUPAF_NO_INHERIT);
+  iupClassRegisterAttribute  (ic, "MARK",      NULL, gtkTreeSetMarkAttrib,      NULL, NULL, IUPAF_WRITEONLY|IUPAF_NO_INHERIT);
+  iupClassRegisterAttribute  (ic, "STARTING",  NULL, gtkTreeSetMarkStartAttrib, NULL, NULL, IUPAF_NO_DEFAULTVALUE|IUPAF_NO_INHERIT);
+  iupClassRegisterAttribute  (ic, "MARKSTART", NULL, gtkTreeSetMarkStartAttrib, NULL, NULL, IUPAF_NO_DEFAULTVALUE|IUPAF_NO_INHERIT);
+  iupClassRegisterAttribute  (ic, "MARKEDNODES", gtkTreeGetMarkedNodesAttrib, gtkTreeSetMarkedNodesAttrib, NULL, NULL, IUPAF_NO_SAVE|IUPAF_NO_DEFAULTVALUE|IUPAF_NO_INHERIT);
+
+  iupClassRegisterAttribute  (ic, "VALUE", gtkTreeGetValueAttrib, gtkTreeSetValueAttrib, NULL, NULL, IUPAF_NO_DEFAULTVALUE|IUPAF_NO_INHERIT);
+
+  /* IupTree Attributes - ACTION */
+  iupClassRegisterAttributeId(ic, "DELNODE", NULL, gtkTreeSetDelNodeAttrib, IUPAF_NOT_MAPPED|IUPAF_WRITEONLY|IUPAF_NO_INHERIT);
+  iupClassRegisterAttribute(ic, "RENAME", NULL, gtkTreeSetRenameAttrib, NULL, NULL, IUPAF_WRITEONLY|IUPAF_NO_INHERIT);
+  iupClassRegisterAttributeId(ic, "MOVENODE", NULL, gtkTreeSetMoveNodeAttrib, IUPAF_NOT_MAPPED|IUPAF_WRITEONLY|IUPAF_NO_INHERIT);
+  iupClassRegisterAttributeId(ic, "COPYNODE", NULL, gtkTreeSetCopyNodeAttrib, IUPAF_NOT_MAPPED|IUPAF_WRITEONLY|IUPAF_NO_INHERIT);
+
+  /* IupTree Attributes - GTK Only */
+  iupClassRegisterAttribute  (ic, "RUBBERBAND", NULL, NULL, IUPAF_SAMEASSYSTEM, "YES", IUPAF_NO_INHERIT);
+}
diff --git a/src/haiku/iuphaiku_val.cpp b/src/haiku/iuphaiku_val.cpp
new file mode 100644
index 0000000..0d279ed
--- /dev/null
+++ b/src/haiku/iuphaiku_val.cpp
@@ -0,0 +1,105 @@
+/** \file
+ * \brief Valuator Control
+ *
+ * See Copyright Notice in "iup.h"
+ */
+
+#define UNIMPLEMENTED printf("%s (%s %d) UNIMPLEMENTED\n",__func__,__FILE__,__LINE__);
+
+#include <Slider.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <memory.h>
+#include <stdarg.h>
+
+#include "iup.h"
+#include "iupcbs.h"
+
+#include "iup_object.h"
+#include "iup_layout.h"
+#include "iup_attrib.h"
+#include "iup_str.h"
+#include "iup_val.h"
+#include "iup_drv.h"
+#include "iup_drvfont.h"
+#include "iup_key.h"
+
+#include "iuphaiku_drv.h"
+
+
+void iupdrvValGetMinSize(Ihandle* ih, int *w, int *h)
+{
+  if (ih->data->orientation == IVAL_HORIZONTAL)
+  {
+    *w = 20;
+    *h = 35;
+  }
+  else
+  {
+    *w = 35;
+    *h = 20;
+  }
+}
+
+static int gtkValSetStepAttrib(Ihandle* ih, const char* value)
+{
+  ih->data->step = atof(value);
+  BSlider* slider = (BSlider*)ih->handle;
+  slider->SetKeyIncrementValue(ih->data->step);
+  return 0; /* do not store value in hash table */
+}
+
+static int gtkValSetPageStepAttrib(Ihandle* ih, const char* value)
+{
+	UNIMPLEMENTED
+  return 0; /* do not store value in hash table */
+}
+
+static int gtkValSetValueAttrib(Ihandle* ih, const char* value)
+{
+	UNIMPLEMENTED
+  return 0; /* do not store value in hash table */
+}
+
+
+/*****************************************************************************/
+
+
+
+static int gtkValMapMethod(Ihandle* ih)
+{
+  BSlider* slider = new BSlider(BRect(0,0,10,10), NULL, NULL, NULL, 0, 100);
+  ih->handle = (InativeHandle*)slider;
+  if (ih->data->orientation == IVAL_HORIZONTAL)
+    slider->SetOrientation(B_HORIZONTAL);
+  else
+    slider->SetOrientation(B_VERTICAL);
+  
+  // TODO handle min/max value at construction (can't change it later...)
+
+  iuphaikuBaseAddToParent(ih);
+  return IUP_NOERROR;
+}
+
+void iupdrvValInitClass(Iclass* ic)
+{
+  /* Driver Dependent Class functions */
+  ic->Map = gtkValMapMethod;
+
+  /* Driver Dependent Attribute functions */
+  
+  /* Visual */
+  iupClassRegisterAttribute(ic, "BGCOLOR", NULL, iupdrvBaseSetBgColorAttrib, IUPAF_SAMEASSYSTEM, "DLGBGCOLOR", IUPAF_DEFAULT); 
+
+  /* IupVal only */
+  iupClassRegisterAttribute(ic, "VALUE", iupValGetValueAttrib, gtkValSetValueAttrib, IUPAF_SAMEASSYSTEM, "0", IUPAF_NO_DEFAULTVALUE|IUPAF_NO_INHERIT);
+  iupClassRegisterAttribute(ic, "PAGESTEP", iupValGetPageStepAttrib, gtkValSetPageStepAttrib, IUPAF_SAMEASSYSTEM, "0.1", IUPAF_NO_INHERIT);
+  iupClassRegisterAttribute(ic, "STEP", iupValGetStepAttrib, gtkValSetStepAttrib, IUPAF_SAMEASSYSTEM, "0.01", IUPAF_NO_INHERIT);
+
+  /* NOT supported */
+  // TODO we actually can support these on Haiku, but we can't support PAGESTEP
+  iupClassRegisterAttribute(ic, "TICKSPOS", NULL, NULL, NULL, NULL, IUPAF_NOT_SUPPORTED|IUPAF_NOT_MAPPED);
+  iupClassRegisterAttribute(ic, "SHOWTICKS", NULL, NULL, NULL, NULL, IUPAF_NOT_SUPPORTED);
+}
diff --git a/src/haiku/iupmac_help.c b/src/haiku/iupmac_help.c
new file mode 100644
index 0000000..fa8d0af
--- /dev/null
+++ b/src/haiku/iupmac_help.c
@@ -0,0 +1,46 @@
+/** \file
+ * \brief MAC Driver IupHelp
+ *
+ * See Copyright Notice in "iup.h"
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "iup.h"
+
+#include "iup_str.h"
+
+int IupHelp(const char *url)
+{
+  char *cmd;
+  int ret;
+  char *browser = getenv("IUP_HELPAPP");
+  if (!browser) 
+    browser = IupGetGlobal("HELPAPP");
+    
+  if (!browser) 
+  { 
+    char* system = IupGetGlobal("SYSTEM"); 
+    if (iupStrEqualNoCase(system, "Snow Leopard") ||
+        iupStrEqualNoCase(system, "Leopard") ||
+        iupStrEqualNoCase(system, "Tiger") ||
+        iupStrEqualNoCase(system, "Panther"))
+      browser = "safari";
+    else if (iupStrEqualNoCase(system, "Jaguar") ||
+        iupStrEqualNoCase(system, "Puma") ||
+        iupStrEqualNoCase(system, "Cheetah"))
+      browser = "iexplore";	  
+    else  /* MacOS */
+      browser = "netscape";
+  }
+  
+  cmd = (char*)malloc(sizeof(char)*(strlen(url)+strlen(browser)+3));
+  sprintf(cmd, "open -a %s %s &", browser, url);
+  ret = system(cmd); 
+  free(cmd);
+  if (ret == -1)
+    return -1;
+  return 1;
+}
diff --git a/srccd/iup_cd.c b/srccd/iup_cd.c
index 619ded7..0b12e72 100644
--- a/srccd/iup_cd.c
+++ b/srccd/iup_cd.c
@@ -23,7 +23,7 @@ static void cdcreatecanvasIUP(cdCanvas* canvas, Ihandle *ih_canvas)
 #endif
   char* data;
 
-  if (cdBaseDriver()==CD_BASE_GDK)
+  if (cdBaseDriver()==CD_BASE_GDK || cdBaseDriver()==CD_BASE_HAIKU)
   {
     data = IupGetAttribute(ih_canvas, "DRAWABLE");  /* new IUP 3 attribute, works for GTK only */
     if (!data)
diff --git a/srcconsole/Makefile b/srcconsole/Makefile
index a9102a3..c35adc9 100644
--- a/srcconsole/Makefile
+++ b/srcconsole/Makefile
@@ -8,7 +8,6 @@ endif
 do_all: iuplua5
  
 iuplua5:
-	@$(TECMAKE_CMD) USE_LUA51=Yes
 	@$(TECMAKE_CMD) USE_LUA52=Yes
 
 iuplua5gtk:
diff --git a/srcgl/config.mak b/srcgl/config.mak
index d569f43..7de22a6 100644
--- a/srcgl/config.mak
+++ b/srcgl/config.mak
@@ -15,6 +15,8 @@ USE_MACOS_OPENGL = Yes
 
 ifneq ($(findstring Win, $(TEC_SYSNAME)), )
   SRC = iup_glcanvas_win.c
+else ifneq ($(findstring Haiku, $(TEC_SYSNAME)), )
+  SRC = iup_glcanvas_haiku.c
 else
   SRC = iup_glcanvas_x.c
   USE_X11 = Yes
diff --git a/srcgl/iup_glcanvas_haiku.c b/srcgl/iup_glcanvas_haiku.c
new file mode 100644
index 0000000..e78cd5e
--- /dev/null
+++ b/srcgl/iup_glcanvas_haiku.c
@@ -0,0 +1,629 @@
+/** \file
+ * \brief iupgl control for Haiku
+ *
+ * See Copyright Notice in "iup.h"
+ */
+
+#include <GL/gl.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <memory.h>
+
+#include "iup.h"
+#include "iupcbs.h"
+#include "iupgl.h"
+
+#include "iup_object.h"
+#include "iup_attrib.h"
+#include "iup_str.h"
+#include "iup_stdcontrols.h"
+#include "iup_assert.h"
+#include "iup_register.h"
+
+
+#ifndef GLX_CONTEXT_MAJOR_VERSION_ARB
+#define GLX_CONTEXT_MAJOR_VERSION_ARB 0x2091
+#define GLX_CONTEXT_MINOR_VERSION_ARB 0x2092
+#define GLX_CONTEXT_FLAGS_ARB 0x2094
+#define GLX_CONTEXT_DEBUG_BIT_ARB 0x0001
+#define GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x0002
+#endif
+
+#ifndef GLX_CONTEXT_PROFILE_MASK_ARB
+#define GLX_CONTEXT_PROFILE_MASK_ARB 0x9126
+#define GLX_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001
+#define GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002
+#endif
+
+
+/* Do NOT use _IcontrolData to make inheritance easy
+   when parent class in glcanvas */
+typedef struct _IGlControlData
+{
+	/* TODO likely store a BGLView here ?
+  Display* display;
+  Drawable window;
+  Colormap colormap;
+  XVisualInfo *vinfo;
+  GLXContext context;*/
+} IGlControlData;
+
+
+static int xGLCanvasDefaultResize(Ihandle *ih, int width, int height)
+{
+  IupGLMakeCurrent(ih);
+  glViewport(0,0,width,height);
+  return IUP_DEFAULT;
+}
+
+static int xGLCanvasCreateMethod(Ihandle* ih, void** params)
+{
+  IGlControlData* gldata;
+  (void)params;
+
+  gldata = (IGlControlData*)malloc(sizeof(IGlControlData));
+  memset(gldata, 0, sizeof(IGlControlData));
+  iupAttribSetStr(ih, "_IUP_GLCONTROLDATA", (char*)gldata);
+
+  IupSetCallback(ih, "RESIZE_CB", (Icallback)xGLCanvasDefaultResize);
+
+  return IUP_NOERROR;
+}
+
+static void xGLCanvasGetVisual(Ihandle* ih, IGlControlData* gldata)
+{
+  int erb, evb, number;
+  int n = 0;
+  int alist[40];
+
+#if 0
+  if (!gldata->display)
+    gldata->display = (Display*)IupGetGlobal("XDISPLAY");  /* works for Motif and GTK, can be called before mapped */
+  if (!gldata->display)
+    return;
+#endif
+
+  /* double or single buffer */
+  if (iupStrEqualNoCase(iupAttribGetStr(ih,"BUFFER"), "DOUBLE"))
+  {
+    //alist[n++] = GLX_DOUBLEBUFFER;
+  }
+
+  /* stereo */
+  if (iupAttribGetBoolean(ih,"STEREO"))
+  {
+    //alist[n++] = GLX_STEREO;
+  }
+
+  /* rgba or index */ 
+  if (iupStrEqualNoCase(iupAttribGetStr(ih,"COLOR"), "INDEX"))
+  {
+    /* buffer size (for index mode) */
+    number = iupAttribGetInt(ih,"BUFFER_SIZE");
+    if (number > 0)
+    {
+      //alist[n++] = GLX_BUFFER_SIZE;
+      alist[n++] = number;
+    }
+  }
+  else
+  {
+    //alist[n++] = GLX_RGBA;      /* assume rgba as default */
+  }
+
+  /* red, green, blue bits */
+  number = iupAttribGetInt(ih,"RED_SIZE");
+  if (number > 0) 
+  {
+    //alist[n++] = GLX_RED_SIZE;
+    //alist[n++] = number;
+  }
+
+  number = iupAttribGetInt(ih,"GREEN_SIZE");
+  if (number > 0) 
+  {
+    //alist[n++] = GLX_GREEN_SIZE;
+    //alist[n++] = number;
+  }
+
+  number = iupAttribGetInt(ih,"BLUE_SIZE");
+  if (number > 0) 
+  {
+    //alist[n++] = GLX_BLUE_SIZE;
+    //alist[n++] = number;
+  }
+
+  number = iupAttribGetInt(ih,"ALPHA_SIZE");
+  if (number > 0) 
+  {
+    //alist[n++] = GLX_ALPHA_SIZE;
+    //alist[n++] = number;
+  }
+
+  /* depth and stencil size */
+  number = iupAttribGetInt(ih,"DEPTH_SIZE");
+  if (number > 0) 
+  {
+    //alist[n++] = GLX_DEPTH_SIZE;
+    //alist[n++] = number;
+  }
+
+  number = iupAttribGetInt(ih,"STENCIL_SIZE");
+  if (number > 0) 
+  {
+    //alist[n++] = GLX_STENCIL_SIZE;
+    //alist[n++] = number;
+  }
+
+  /* red, green, blue accumulation bits */
+  number = iupAttribGetInt(ih,"ACCUM_RED_SIZE");
+  if (number > 0) 
+  {
+    //alist[n++] = GLX_ACCUM_RED_SIZE;
+    //alist[n++] = number;
+  }
+
+  number = iupAttribGetInt(ih,"ACCUM_GREEN_SIZE");
+  if (number > 0) 
+  {
+    //alist[n++] = GLX_ACCUM_GREEN_SIZE;
+    //alist[n++] = number;
+  }
+
+  number = iupAttribGetInt(ih,"ACCUM_BLUE_SIZE");
+  if (number > 0) 
+  {
+    //alist[n++] = GLX_ACCUM_BLUE_SIZE;
+    //alist[n++] = number;
+  }
+
+  number = iupAttribGetInt(ih,"ACCUM_ALPHA_SIZE");
+  if (number > 0) 
+  {
+    //alist[n++] = GLX_ACCUM_ALPHA_SIZE;
+    //alist[n++] = number;
+  }
+  //alist[n++] = None;
+
+  /* check out X extension */
+  /*
+  if (!glXQueryExtension(gldata->display, &erb, &evb))
+  {
+    iupAttribSetStr(ih, "ERROR", "X server has no OpenGL GLX extension");
+    return;
+  }
+  */
+
+  /* choose visual */
+  /*
+  gldata->vinfo = glXChooseVisual(gldata->display, DefaultScreen(gldata->display), alist);
+  if (!gldata->vinfo)
+  {
+    iupAttribSetStr(ih, "ERROR", "No appropriate visual");
+    return;
+  }
+  */
+
+  iupAttribSetStr(ih, "ERROR", NULL);
+}
+
+static char* xGLCanvasGetVisualAttrib(Ihandle *ih)
+{
+  IGlControlData* gldata = (IGlControlData*)iupAttribGet(ih, "_IUP_GLCONTROLDATA");
+
+  /* This must be available before mapping, because IupCanvas uses it during map in GTK and Motif. */
+  /*
+  if (gldata->vinfo)
+    return (char*)gldata->vinfo->visual;
+*/
+  xGLCanvasGetVisual(ih, gldata);
+/*
+  if (gldata->vinfo)
+    return (char*)gldata->vinfo->visual;
+*/
+  return NULL;
+}
+
+static int xGLCanvasMapMethod(Ihandle* ih)
+{
+  IGlControlData* gldata = (IGlControlData*)iupAttribGet(ih, "_IUP_GLCONTROLDATA");
+  //GLXContext shared_context = NULL;
+  Ihandle* ih_shared;
+
+  /* the IupCanvas is already mapped, just initialize the OpenGL context */
+
+  if (!xGLCanvasGetVisualAttrib(ih))
+    return IUP_NOERROR; /* do not abort mapping */
+#if 0
+  gldata->window = (XID)iupAttribGet(ih, "XWINDOW"); /* check first in the hash table, can be defined by the IupFileDlg */
+  if (!gldata->window)
+    gldata->window = (XID)IupGetAttribute(ih, "XWINDOW");  /* works for Motif and GTK, only after mapping the IupCanvas */
+  if (!gldata->window)
+    return IUP_NOERROR;
+#endif
+  ih_shared = IupGetAttributeHandle(ih, "SHAREDCONTEXT");
+  if (ih_shared && IupClassMatch(ih_shared, "glcanvas"))  /* must be an IupGLCanvas */
+  {
+    IGlControlData* shared_gldata = (IGlControlData*)iupAttribGet(ih_shared, "_IUP_GLCONTROLDATA");
+    //shared_context = shared_gldata->context;
+  }
+
+  /* create rendering context */
+  if (iupAttribGetBoolean(ih, "ARBCONTEXT"))
+  {
+#if 0
+    glXCreateContextAttribsARB_PROC CreateContextAttribsARB = NULL;
+
+    GLXContext tempContext = glXCreateContext(gldata->display, gldata->vinfo, NULL, GL_TRUE);
+    GLXContext oldContext = glXGetCurrentContext();
+    Display* oldDisplay = glXGetCurrentDisplay();
+    GLXDrawable oldDrawable = glXGetCurrentDrawable();
+    glXMakeCurrent(gldata->display, gldata->window, tempContext);   /* glXGetProcAddress only works with an active context */
+
+    CreateContextAttribsARB = (glXCreateContextAttribsARB_PROC)glXGetProcAddress((const GLubyte*)"glXCreateContextAttribsARB");
+#endif
+//    if (CreateContextAttribsARB)
+    {
+      int attribs[9], a = 0;
+      char* value;
+
+	    int nelements;
+	  //  GLXFBConfig *config = glXChooseFBConfig(gldata->display, DefaultScreen(gldata->display), 0, &nelements);
+
+      value = iupAttribGetStr(ih, "CONTEXTVERSION");
+      if (value)
+      {
+        int major, minor;
+        if (iupStrToIntInt(value, &major, &minor, '.') == 2)
+        {
+          attribs[a++] = GLX_CONTEXT_MAJOR_VERSION_ARB;
+          attribs[a++] = major;
+          attribs[a++] = GLX_CONTEXT_MINOR_VERSION_ARB;
+          attribs[a++] = minor;
+        }
+      }
+
+      value = iupAttribGetStr(ih, "CONTEXTFLAGS");
+      if (value)
+      {
+        int flags = 0;
+        if (iupStrEqualNoCase(value, "DEBUG"))
+          flags = GLX_CONTEXT_DEBUG_BIT_ARB;
+        else if (iupStrEqualNoCase(value, "FORWARDCOMPATIBLE"))
+          flags = GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB;
+        else if (iupStrEqualNoCase(value, "DEBUGFORWARDCOMPATIBLE"))
+          flags = GLX_CONTEXT_DEBUG_BIT_ARB|GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB;
+        if (flags)
+        {
+          attribs[a++] = GLX_CONTEXT_FLAGS_ARB;
+          attribs[a++] = flags;
+        }
+      }
+
+      value = iupAttribGetStr(ih, "CONTEXTPROFILE");
+      if (value)
+      {
+        int profile = 0;
+        if (iupStrEqualNoCase(value, "CORE"))
+          profile = GLX_CONTEXT_CORE_PROFILE_BIT_ARB;
+        else if (iupStrEqualNoCase(value, "COMPATIBILITY"))
+          profile = GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB;
+        else if (iupStrEqualNoCase(value, "CORECOMPATIBILITY"))
+          profile = GLX_CONTEXT_CORE_PROFILE_BIT_ARB|GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB;
+        if (profile)
+        {
+          attribs[a++] = GLX_CONTEXT_PROFILE_MASK_ARB;
+          attribs[a++] = profile;
+        }
+      }
+
+      attribs[a] = 0; /* terminator */
+      
+      //gldata->context = CreateContextAttribsARB(gldata->display, *config, shared_context, GL_TRUE, attribs);
+    }
+/*
+    glXMakeCurrent(oldDisplay, oldDrawable, oldContext);
+    glXDestroyContext(gldata->display, tempContext);
+
+    if (!CreateContextAttribsARB)
+*/
+    {
+//      gldata->context = glXCreateContext(gldata->display, gldata->vinfo, shared_context, GL_TRUE);
+      iupAttribSetStr(ih, "ARBCONTEXT", "NO");
+    }
+  }
+  else
+//    gldata->context = glXCreateContext(gldata->display, gldata->vinfo, shared_context, GL_TRUE);
+/*
+  if (!gldata->context)
+  {
+    iupAttribSetStr(ih, "ERROR", "Could not create a rendering context");
+    return IUP_NOERROR;
+  }
+
+  iupAttribSetStr(ih, "CONTEXT", (char*)gldata->context);
+*/
+  /* create colormap for index mode */
+#if 0
+  if (iupStrEqualNoCase(iupAttribGetStr(ih,"COLOR"), "INDEX") && 
+      gldata->vinfo->class != StaticColor && gldata->vinfo->class != StaticGray)
+  {
+    gldata->colormap = XCreateColormap(gldata->display, RootWindow(gldata->display, DefaultScreen(gldata->display)), gldata->vinfo->visual, AllocAll);
+    iupAttribSetStr(ih, "COLORMAP", (char*)gldata->colormap);
+  }
+
+  if (gldata->colormap != None)
+    IupGLPalette(ih,0,1,1,1);  /* set first color as white */
+#endif
+  iupAttribSetStr(ih, "ERROR", NULL);
+  return IUP_NOERROR;
+}
+
+static void xGLCanvasDestroy(Ihandle* ih)
+{
+  IGlControlData* gldata = (IGlControlData*)iupAttribGet(ih, "_IUP_GLCONTROLDATA");
+  free(gldata);
+  iupAttribSetStr(ih, "_IUP_GLCONTROLDATA", NULL);
+}
+
+static void xGLCanvasUnMapMethod(Ihandle* ih)
+{
+  IGlControlData* gldata = (IGlControlData*)iupAttribGet(ih, "_IUP_GLCONTROLDATA");
+#if 0
+  if (gldata->context)
+  {
+    if (gldata->context == glXGetCurrentContext())
+      glXMakeCurrent(gldata->display, None, NULL);
+
+    glXDestroyContext(gldata->display, gldata->context);
+  }
+
+  if (gldata->colormap != None)
+    XFreeColormap(gldata->display, gldata->colormap);
+
+  if (gldata->vinfo)
+    XFree(gldata->vinfo); 
+#endif
+  memset(gldata, 0, sizeof(IGlControlData));
+}
+
+static Iclass* xGlCanvasNewClass(void)
+{
+  Iclass* ic = iupClassNew(iupRegisterFindClass("canvas"));
+
+  ic->name = "glcanvas";
+  ic->format = "a"; /* one ACTION callback name */
+  ic->nativetype = IUP_TYPECANVAS;
+  ic->childtype = IUP_CHILDNONE;
+  ic->is_interactive = 1;
+
+  ic->New = xGlCanvasNewClass;
+  ic->Create = xGLCanvasCreateMethod;
+  ic->Destroy = xGLCanvasDestroy;
+  ic->Map = xGLCanvasMapMethod;
+  ic->UnMap = xGLCanvasUnMapMethod;
+
+  iupClassRegisterAttribute(ic, "BUFFER", NULL, NULL, IUPAF_SAMEASSYSTEM, "SINGLE", IUPAF_DEFAULT);
+  iupClassRegisterAttribute(ic, "COLOR", NULL, NULL, IUPAF_SAMEASSYSTEM, "RGBA", IUPAF_DEFAULT);
+  iupClassRegisterAttribute(ic, "ERROR", NULL, NULL, NULL, NULL, IUPAF_NO_INHERIT);
+
+  iupClassRegisterAttribute(ic, "CONTEXT", NULL, NULL, NULL, NULL, IUPAF_READONLY|IUPAF_NO_STRING);
+  iupClassRegisterAttribute(ic, "VISUAL", xGLCanvasGetVisualAttrib, NULL, NULL, NULL, IUPAF_READONLY|IUPAF_NO_STRING|IUPAF_NOT_MAPPED);
+  iupClassRegisterAttribute(ic, "COLORMAP", NULL, NULL, NULL, NULL, IUPAF_READONLY|IUPAF_NO_STRING);
+
+  iupClassRegisterAttribute(ic, "CONTEXTFLAGS", NULL, NULL, NULL, NULL, IUPAF_NO_INHERIT);
+  iupClassRegisterAttribute(ic, "CONTEXTPROFILE", NULL, NULL, NULL, NULL, IUPAF_NO_INHERIT);
+  iupClassRegisterAttribute(ic, "CONTEXTVERSION", NULL, NULL, NULL, NULL, IUPAF_NO_INHERIT);
+  iupClassRegisterAttribute(ic, "ARBCONTEXT", NULL, NULL, NULL, NULL, IUPAF_NO_INHERIT);
+
+  return ic;
+}
+
+
+/******************************************* Exported functions */
+
+void IupGLCanvasOpen(void)
+{
+  if (!IupGetGlobal("_IUP_GLCANVAS_OPEN"))
+  {
+    iupRegisterClass(xGlCanvasNewClass());
+    IupSetGlobal("_IUP_GLCANVAS_OPEN", "1");
+  }
+}
+
+Ihandle* IupGLCanvas(const char *action)
+{
+  void *params[2];
+  params[0] = (void*)action;
+  params[1] = NULL;
+  return IupCreatev("glcanvas", params);
+}
+
+int IupGLIsCurrent(Ihandle* ih)
+{
+  IGlControlData* gldata;
+
+  iupASSERT(iupObjectCheck(ih));
+  if (!iupObjectCheck(ih))
+    return 0;
+
+  /* must be an IupGLCanvas */
+  if (ih->iclass->nativetype != IUP_TYPECANVAS || 
+      !IupClassMatch(ih, "glcanvas"))
+    return 0;
+
+  /* must be mapped */
+  gldata = (IGlControlData*)iupAttribGet(ih, "_IUP_GLCONTROLDATA");
+/*
+  if (!gldata->window)
+    return 0;
+
+  if (gldata->context == glXGetCurrentContext())
+    return 1;
+*/
+  return 0;
+}
+
+void IupGLMakeCurrent(Ihandle* ih)
+{
+  IGlControlData* gldata;
+
+  iupASSERT(iupObjectCheck(ih));
+  if (!iupObjectCheck(ih))
+    return;
+
+  /* must be an IupGLCanvas */
+  if (ih->iclass->nativetype != IUP_TYPECANVAS || 
+      !IupClassMatch(ih, "glcanvas"))
+    return;
+
+  /* must be mapped */
+  gldata = (IGlControlData*)iupAttribGet(ih, "_IUP_GLCONTROLDATA");
+#if 0
+  if (!gldata->window)
+    return;
+
+  if (glXMakeCurrent(gldata->display, gldata->window, gldata->context)==False)
+    iupAttribSetStr(ih, "ERROR", "Failed to set new current context");
+  else
+  {
+    iupAttribSetStr(ih, "ERROR", NULL);
+    glXWaitX();
+  }
+#endif
+}
+
+void IupGLSwapBuffers(Ihandle* ih)
+{
+  IGlControlData* gldata;
+
+  iupASSERT(iupObjectCheck(ih));
+  if (!iupObjectCheck(ih))
+    return;
+
+  /* must be an IupGLCanvas */
+  if (ih->iclass->nativetype != IUP_TYPECANVAS || 
+      !IupClassMatch(ih, "glcanvas"))
+    return;
+
+  /* must be mapped */
+  gldata = (IGlControlData*)iupAttribGet(ih, "_IUP_GLCONTROLDATA");
+/*
+  if (!gldata->window)
+    return;
+
+  glXSwapBuffers(gldata->display, gldata->window);
+*/
+}
+
+/*
+static int xGLCanvasIgnoreError(Display *param1, XErrorEvent *param2)
+{
+  (void)param1;
+  (void)param2;
+  return 0;
+}
+*/
+
+void IupGLPalette(Ihandle* ih, int index, float r, float g, float b)
+{
+  IGlControlData* gldata;
+//  XColor color;
+  int rShift, gShift, bShift;
+//  XVisualInfo *vinfo;
+//  XErrorHandler old_handler;
+
+  iupASSERT(iupObjectCheck(ih));
+  if (!iupObjectCheck(ih))
+    return;
+
+  /* must be an IupGLCanvas */
+  if (ih->iclass->nativetype != IUP_TYPECANVAS || 
+      !IupClassMatch(ih, "glcanvas"))
+    return;
+
+  /* must be mapped */
+  gldata = (IGlControlData*)iupAttribGet(ih, "_IUP_GLCONTROLDATA");
+#if 0
+  if (!gldata->window)
+    return;
+
+  /* must have a colormap */
+  if (gldata->colormap == None)
+    return;
+
+  /* code fragment based on the toolkit library provided with OpenGL */
+  old_handler = XSetErrorHandler(xGLCanvasIgnoreError);
+
+  vinfo = gldata->vinfo;
+  switch (vinfo->class) 
+  {
+  case DirectColor:
+    rShift = ffs((unsigned int)vinfo->red_mask) - 1;
+    gShift = ffs((unsigned int)vinfo->green_mask) - 1;
+    bShift = ffs((unsigned int)vinfo->blue_mask) - 1;
+    color.pixel = ((index << rShift) & vinfo->red_mask) |
+                  ((index << gShift) & vinfo->green_mask) |
+                  ((index << bShift) & vinfo->blue_mask);
+    color.red = (unsigned short)(r * 65535.0 + 0.5);
+    color.green = (unsigned short)(g * 65535.0 + 0.5);
+    color.blue = (unsigned short)(b * 65535.0 + 0.5);
+    color.flags = DoRed | DoGreen | DoBlue;
+    XStoreColor(gldata->display, gldata->colormap, &color);
+    break;
+  case GrayScale:
+  case PseudoColor:
+    if (index < vinfo->colormap_size) 
+    {
+      color.pixel = index;
+      color.red = (unsigned short)(r * 65535.0 + 0.5);
+      color.green = (unsigned short)(g * 65535.0 + 0.5);
+      color.blue = (unsigned short)(b * 65535.0 + 0.5);
+      color.flags = DoRed | DoGreen | DoBlue;
+      XStoreColor(gldata->display, gldata->colormap, &color);
+    }
+    break;
+  }
+
+  XSync(gldata->display, 0);
+  XSetErrorHandler(old_handler);
+#endif
+}
+
+void IupGLUseFont(Ihandle* ih, int first, int count, int list_base)
+{
+  IGlControlData* gldata;
+//  Font font;
+
+  iupASSERT(iupObjectCheck(ih));
+  if (!iupObjectCheck(ih))
+    return;
+
+  /* must be an IupGLCanvas */
+  if (ih->iclass->nativetype != IUP_TYPECANVAS || 
+      !IupClassMatch(ih, "glcanvas"))
+    return;
+
+  /* must be mapped */
+  gldata = (IGlControlData*)iupAttribGet(ih, "_IUP_GLCONTROLDATA");
+/*
+  if (!gldata->window)
+    return;
+
+  font = (Font)IupGetAttribute(ih, "XFONTID");
+  if (font)
+    glXUseXFont(font, first, count, list_base);
+*/
+}
+
+void IupGLWait(int gl)
+{
+/*
+  if (gl)
+    glXWaitGL();
+  else
+    glXWaitX();
+*/
+}
diff --git a/srcimglib/iup_image_library.c b/srcimglib/iup_image_library.c
index 575e433..93747ce 100644
--- a/srcimglib/iup_image_library.c
+++ b/srcimglib/iup_image_library.c
@@ -28,7 +28,7 @@ void IupImageLibOpen(void)
   driver = IupGetGlobal("DRIVER");
   if (iupStrEqualNoCase(driver, "GTK"))
     gtk = 1;
-  else if (iupStrEqualNoCase(driver, "Motif"))
+  else if (iupStrEqualNoCase(driver, "Motif") || iupStrEqualNoCase(driver, "Haiku"))
     motif = 1;
   else if (iupStrEqualNoCase(driver, "Win32"))
     win32 = 1;
diff --git a/srclua5/Makefile b/srclua5/Makefile
index 9c597fb..486cf17 100644
--- a/srclua5/Makefile
+++ b/srclua5/Makefile
@@ -6,7 +6,7 @@ else
 endif
 
 .PHONY: do_all iuplua iupluacd iupluacontrols iupluagl iuplua_pplot iuplua_mglplot iuplua_scintilla iupluaim iupluaimglib iupluatuio iupluaole iupluaweb
-do_all: iuplua iupluacd iupluacontrols iupluagl iuplua_pplot iuplua_mglplot iuplua_scintilla iupluaim iupluaimglib iupluatuio $(WINLIBS)
+do_all: iuplua iupluacd iupluacontrols iupluagl iuplua_pplot iuplua_mglplot iupluaim iupluaimglib iupluatuio $(WINLIBS)
 
 iuplua:
 	@$(TECMAKE_CMD) USE_LUA51=Yes 
diff --git a/srcmglplot/mgl/mgl_ab.h b/srcmglplot/mgl/mgl_ab.h
index 7c47201..35c1b1e 100644
--- a/srcmglplot/mgl/mgl_ab.h
+++ b/srcmglplot/mgl/mgl_ab.h
@@ -32,10 +32,12 @@
 class mglGraphAB : public mglGraph
 {
 public:
-using mglGraph::Mark;
-using mglGraph::Ball;
-//using mglGraph::Colorbar;
-using mglGraph::Legend;
+#if (!defined(__GNUC__) || (__GNUC__ > 2))
+	using mglGraph::Mark;
+	using mglGraph::Ball;
+	//using mglGraph::Colorbar;
+	using mglGraph::Legend;
+#endif
 	int *OI;	///< ObjId arrays
 	int ObjId;	///< object id for mglPrim
 
diff --git a/srcmglplot/mgl/mgl_axis.cpp b/srcmglplot/mgl/mgl_axis.cpp
index d81c014..0685ce2 100644
--- a/srcmglplot/mgl/mgl_axis.cpp
+++ b/srcmglplot/mgl/mgl_axis.cpp
@@ -1021,7 +1021,9 @@ void mglGraph::Legend(int n, wchar_t **text,char **style, int where,
 //-----------------------------------------------------------------------------
 void mglGraph::Ternary(int t)
 {
-	static mglPoint x1(-1,-1,-1),x2(1,1,1),o(NAN,NAN,NAN);
+	static mglPoint x1(-1,-1,-1);
+	static mglPoint x2(1,1,1);
+	static mglPoint o(NAN,NAN,NAN);
 	static bool c = true;
 	TernAxis = t;
 	if(t)
diff --git a/srcscintilla/Makefile b/srcscintilla/Makefile
index 639ab7d..07f0d5f 100644
--- a/srcscintilla/Makefile
+++ b/srcscintilla/Makefile
@@ -7,5 +7,5 @@ endif
 .PHONY: do_all iup_scintilla
 do_all: iup_scintilla
 
-iup_mglplot:
+iup_scintilla:
 	@$(TECMAKE_CMD) 
diff --git a/srcview/config.mak b/srcview/config.mak
index 742f92e..7e71767 100644
--- a/srcview/config.mak
+++ b/srcview/config.mak
@@ -11,6 +11,10 @@ LINKER = $(CPPC)
 USE_IUPCONTROLS = Yes
 USE_IUP3 = Yes
 
+ifeq "$(TEC_SYSNAME)" "Haiku"
+  USE_HAIKU = Yes
+else
+  USE_STATIC = Yes
 ifdef GTK_DEFAULT
   ifdef USE_MOTIF
     # Build Motif version in Linux and BSD
@@ -22,8 +26,8 @@ else
     APPNAME := $(APPNAME)gtk
   endif
 endif
+endif
 
-USE_STATIC = Yes
 
 ifeq "$(TEC_UNAME)" "SunOS510x86"
   DEFINES += USE_NO_OPENGL
diff --git a/tec_uname b/tec_uname
index cc89349..fc982e0 100644
--- a/tec_uname
+++ b/tec_uname
@@ -148,6 +148,11 @@ ComputeSystemPaths()
 
   TEC_SYSTEM_INC=/usr/include
   
+  if [ $TEC_SYSNAME == Haiku ]; then
+  	TEC_SYSTEM_LIB=`finddir B_SYSTEM_LIB_DIRECTORY`
+  	TEC_SYSTEM_INC=`finddir B_SYSTEM_HEADERS_DIRECTORY`
+  fi
+
   TEC_LUA_LIB=$TEC_SYSTEM_LIB/lua/$LUA_VER
 }
 
diff --git a/tecmake.mak b/tecmake.mak
index e5f5efd..1e09d6c 100644
--- a/tecmake.mak
+++ b/tecmake.mak
@@ -26,6 +26,9 @@ ifndef TEC_UNAME
   TEC_SYSARCH:=$(shell uname -m)
 
   # Fixes
+  ifeq ($(TEC_SYSNAME), Haiku)
+    TEC_SYSARCH:=$(shell uname -p)
+  endif
   ifeq ($(TEC_SYSNAME), SunOS)
     TEC_SYSARCH:=$(shell uname -p)
   endif
@@ -505,6 +508,12 @@ else
   endif
 endif
 
+
+ifeq "$(TEC_SYSNAME)" "Haiku"
+  STDFLAGS += -Wno-multichar
+  LIBS += be textencoding tracker
+endif
+
 ifneq ($(findstring Linux, $(TEC_UNAME)), )
   UNIX_LINUX = Yes
   ifdef BUILD_64
@@ -526,6 +535,11 @@ ifneq ($(findstring Linux, $(TEC_UNAME)), )
   endif
 endif
 
+ifneq ($(findstring Haiku, $(TEC_UNAME)), )
+  UNIX_POSIX = Yes
+  STDLDFLAGS := -shared -Wl,-soname=lib$(TARGETNAME).so
+endif
+
 ifneq ($(findstring IRIX, $(TEC_UNAME)), )
   UNIX_POSIX = Yes
   ifndef NO_LOCAL_LD
@@ -852,6 +866,7 @@ endif
 ifdef USE_IUP
   IUP_SUFFIX ?=
   ifdef USE_IUP3
+	ifndef USE_HAIKU
     ifdef GTK_DEFAULT
       ifdef USE_MOTIF
         IUP_SUFFIX := mot
@@ -869,6 +884,7 @@ ifdef USE_IUP
         endif
       endif
     endif
+    endif
   else
     ifndef NO_OVERRIDE
       override USE_MOTIF = Yes
@@ -956,6 +972,11 @@ ifdef USE_CD
       LIBS += cdcairo
       LIBS += pangocairo-1.0 cairo
     endif
+
+    ifdef USE_HAIKU
+	  LINK_FREETYPE = Yes
+	  LIBS += fontconfig xml2
+	endif
     
     LIBS += cd$(CD_SUFFIX)
     LDIR += $(CD_LIB)
@@ -1180,7 +1201,9 @@ ifdef USE_X11
   STDINCS += $(X11_INC)
 endif
 
-LIBS += m
+ifneq "$(TEC_SYSNAME)" "Haiku"
+  LIBS += m
+endif
 
 ifneq ($(findstring cygw, $(TEC_UNAME)), )
   WIN_OTHER := Yes
diff --git a/test/config.mak b/test/config.mak
index 8d558b2..6db8745 100644
--- a/test/config.mak
+++ b/test/config.mak
@@ -20,6 +20,11 @@ USE_IUP3 = Yes
 USE_STATIC = Yes
 IUP = ..
 
+ifeq "$(TEC_SYSNAME)" "Haiku"
+  USE_HAIKU = Yes
+  USE_STATIC = No
+endif
+
 ifdef DBG_DIR
   IUPLIB = $(IUP)/lib/$(TEC_UNAME)d
   CDLIB = $(CD)/lib/$(TEC_UNAME)d
-- 
1.8.3.4

