Files
haikuports/x11-libs/iup/patches/iup-3.8.patchset
Adrien Destugues 6fb6ba0f93 cd,iup: support hybrid builds
* Untested, as IM fails to build for a non-identified reason.
2013-11-16 21:59:31 +01:00

8067 lines
210 KiB
Plaintext

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