From 3af24979604dec542dc0df741796c5103c0f0615 Mon Sep 17 00:00:00 2001 From: Adrien Destugues Date: Fri, 15 Nov 2013 23:45:03 +0100 Subject: [PATCH] WIP recipe for IUP * Rebase the work I did against latest IUP release * Currently fails to build because IUP wants to generate both Lua 5.1 and 5.2 bindings. It seems we can't build_require both packages to build the bindings ? (require should be ok, as the libs for each version will go in different packages in the end). * Also, port some of the fixes to tecmake to the two other tecgraf libs using it. --- media-libs/im/patches/im-3.8.patchset | 16 +- x11-libs/cd/patches/cd-5.6.patchset | 28 +- x11-libs/iup/iup-3.8.recipe | 70 + x11-libs/iup/patches/iup-3.8.patchset | 8005 +++++++++++++++++++++++++ 4 files changed, 8107 insertions(+), 12 deletions(-) create mode 100644 x11-libs/iup/iup-3.8.recipe create mode 100644 x11-libs/iup/patches/iup-3.8.patchset diff --git a/media-libs/im/patches/im-3.8.patchset b/media-libs/im/patches/im-3.8.patchset index 05772cb31..2a03da9ce 100644 --- a/media-libs/im/patches/im-3.8.patchset +++ b/media-libs/im/patches/im-3.8.patchset @@ -1,4 +1,4 @@ -From 25622aa79bc39c13f2d8f55a6a0572e34d06b962 Mon Sep 17 00:00:00 2001 +From 6421d3e8c775ddb4477f4418a983d5bfa2b901f0 Mon Sep 17 00:00:00 2001 From: Adrien Destugues Date: Thu, 14 Nov 2013 21:46:53 +0100 Subject: Make tecmake aware of Haiku and the lack of libm. @@ -21,10 +21,20 @@ index cc89349..fc982e0 100755 } diff --git a/tecmake.mak b/tecmake.mak -index f799a07..f317af2 100755 +index f799a07..7ee8895 100755 --- a/tecmake.mak +++ b/tecmake.mak -@@ -1177,7 +1177,9 @@ ifdef USE_X11 +@@ -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 +@@ -1177,7 +1180,9 @@ ifdef USE_X11 STDINCS += $(X11_INC) endif diff --git a/x11-libs/cd/patches/cd-5.6.patchset b/x11-libs/cd/patches/cd-5.6.patchset index 2adc709c2..4948b189a 100644 --- a/x11-libs/cd/patches/cd-5.6.patchset +++ b/x11-libs/cd/patches/cd-5.6.patchset @@ -1,4 +1,4 @@ -From 1274927462310ff54a257900076c5deed9559a13 Mon Sep 17 00:00:00 2001 +From 49ce8054eee01b9a146ff7a7ee77303b7834b2a5 Mon Sep 17 00:00:00 2001 From: Adrien Destugues Date: Fri, 15 Nov 2013 21:59:25 +0100 Subject: Import Haiku port sources. @@ -688,7 +688,7 @@ index cc89349..fc982e0 100644 } diff --git a/tecmake.mak b/tecmake.mak -index e5f5efd..169d45f 100644 +index e5f5efd..6463f3c 100644 --- a/tecmake.mak +++ b/tecmake.mak @@ -6,7 +6,7 @@ @@ -700,7 +700,17 @@ index e5f5efd..169d45f 100644 #---------------------------------# -@@ -505,6 +505,11 @@ else +@@ -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,11 @@ else endif endif @@ -712,7 +722,7 @@ index e5f5efd..169d45f 100644 ifneq ($(findstring Linux, $(TEC_UNAME)), ) UNIX_LINUX = Yes ifdef BUILD_64 -@@ -852,6 +857,7 @@ endif +@@ -852,6 +860,7 @@ endif ifdef USE_IUP IUP_SUFFIX ?= ifdef USE_IUP3 @@ -720,7 +730,7 @@ index e5f5efd..169d45f 100644 ifdef GTK_DEFAULT ifdef USE_MOTIF IUP_SUFFIX := mot -@@ -869,6 +875,7 @@ ifdef USE_IUP +@@ -869,6 +878,7 @@ ifdef USE_IUP endif endif endif @@ -728,7 +738,7 @@ index e5f5efd..169d45f 100644 else ifndef NO_OVERRIDE override USE_MOTIF = Yes -@@ -902,17 +909,21 @@ endif +@@ -902,17 +912,21 @@ endif ifdef USE_CD CD_SUFFIX ?= @@ -761,7 +771,7 @@ index e5f5efd..169d45f 100644 endif endif endif -@@ -993,7 +1004,6 @@ endif +@@ -993,7 +1007,6 @@ endif ifdef LINK_FREETYPE FREETYPE = freetype ifneq ($(findstring cygw, $(TEC_UNAME)), ) @@ -769,7 +779,7 @@ index e5f5efd..169d45f 100644 FREETYPE = freetype-6 endif -@@ -1138,23 +1148,21 @@ ifdef USE_GTK +@@ -1138,23 +1151,21 @@ ifdef USE_GTK ifndef USE_GTK3 STDINCS += $(GTK)/lib/x86_64-linux-gnu/gtk-2.0/include endif @@ -808,7 +818,7 @@ index e5f5efd..169d45f 100644 endif endif -@@ -1180,7 +1188,9 @@ ifdef USE_X11 +@@ -1180,7 +1191,9 @@ ifdef USE_X11 STDINCS += $(X11_INC) endif diff --git a/x11-libs/iup/iup-3.8.recipe b/x11-libs/iup/iup-3.8.recipe new file mode 100644 index 000000000..0f143aebd --- /dev/null +++ b/x11-libs/iup/iup-3.8.recipe @@ -0,0 +1,70 @@ +SUMMARY="IUP is a multi-platform toolkit for building graphical user interfaces." +HOMEPAGE="http://www.tecgraf.puc-rio.br/iup/" +SRC_URI="http://downloads.sourceforge.net/project/iup/3.8/Docs%20and%20Sources/iup-3.8_Sources.zip" # The tar.gz has permission problems. +CHECKSUM_MD5="b14469c2dd46af3e1bb1ecc8dc216061" +REVISION="1" +ARCHITECTURES="x86_gcc2" +PROVIDES=" + iup = $portVersion + " +REQUIRES=" + lib:liblua + lib:libcd >= 5.6 + lib:libim >= 3.8 +" + +BUILD_REQUIRES=" + haiku_devel$secondaryArchSuffix >= $haikuVersion + cmd:gcc$secondaryArchSuffix + cmd:make + cmd:which + cmd:yacc + devel:libcd + devel:libfontconfig + devel:libfreetype + devel:libGLU + devel:libim + devel:liblua + devel:libxml2 + devel:libz +" + +SOURCE_DIR="iup" +PATCHES="iup-3.8.patchset" +BUILD() +{ + make +} + +INSTALL() +{ + mkdir -p $developLibDir + mkdir -p $libDir + mkdir -p $includeDir + + # These are built as dependencies instead of using the system ones... + rm lib/Haiku11/libz.* + rm lib/Haiku11/libfreetype.* + + cp lib/Haiku11/*.so $libDir + cp lib/Haiku11/*.a $developLibDir + cp include/* $includeDir + + # Won't work, the libs have no soname... +# prepareInstalledDevelLib libim +# libim libim_fftw libim_jp2 libim_process libim_process_omp \ +# libimlua51 libimlua_fftw51 libimlua_jp251 libimlua_process51 libimlua_process_omp51 \ +# libimlua52 libimlua_fftw52 libimlua_jp252 libimlua_process52 libimlua_process_omp52 + + packageEntries devel $developDir +} + +LICENSE="MIT" +COPYRIGHT="1994-2013 Tecgraf, PUC-Rio." +DESCRIPTION="IUP is a multi-platform toolkit for building graphical user interfaces. It offers APIs in three basic languages: C, Lua and LED. + +Its library contains about 100 functions for creating and manipulating dialogs. + +IUP's purpose is to allow a program to run in different systems without changes - the toolkit provides the application portability. Supported systems include: GTK+, Motif and Windows. + +IUP uses an abstract layout model based on the boxes-and-glue paradigm from the TEX text editor. This model, combined with the dialog-specification language (LED) or with the Lua binding (IupLua) makes the dialog creation task more flexible and independent from the graphics system's resolution." diff --git a/x11-libs/iup/patches/iup-3.8.patchset b/x11-libs/iup/patches/iup-3.8.patchset new file mode 100644 index 000000000..aa81f36e1 --- /dev/null +++ b/x11-libs/iup/patches/iup-3.8.patchset @@ -0,0 +1,8005 @@ +From 736ca6335b2068828da740c705994a6ca409d915 Mon Sep 17 00:00:00 2001 +From: Adrien Destugues +Date: Fri, 15 Nov 2013 22:50:38 +0100 +Subject: Import Haiku port work. + + +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 ++#include ++#include ++#include ++ ++#include ++ ++#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; iimage_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 ++#include ++#if GTK_CHECK_VERSION(3, 0, 0) ++#include ++#endif ++ ++#include ++#include ++ ++#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 ++ ++#include ++#include ++#include ++#include ++#include ++ ++#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 ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#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 ++#include ++#include ++ ++#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 ++#include ++#include ++ ++#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 ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++ ++#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(handler); ++ if (window) ++ return window->ChildAt(0); // Get background view ++ else ++ return dynamic_cast(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(handler); ++ BWindow* window = dynamic_cast(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(handler); ++ if (control && !control->IsEnabled()) ++ return false; ++ return true; ++} ++ ++void iupdrvSetActive(Ihandle* ih, int enable) ++{ ++ BHandler* handler = (BHandler*)ih->handle; ++ ++ BView* view = dynamic_cast(handler); ++ BWindow* window = dynamic_cast(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 ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#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(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 ++#include ++#include ++#include ++ ++#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 ++#include ++#include ++#include ++ ++#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 ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++ ++#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 ++ ++#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 ++#include ++#include ++ ++#include ++#include ++ ++#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 ++ ++#include ++#include ++ ++#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 ++#include ++ ++#include ++#include ++#include ++#include ++#include ++ ++#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 ++#include ++ ++#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 ++#include ++#include ++ ++#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 ++#include ++#include ++#include ++ ++#include ++#include ++#include ++ ++#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; ycurrentheight; y++) ++ for (int x=0; xcurrentwidth; 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; ycurrentheight; y++) ++ for (int x=y&1; xcurrentwidth; 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 ++#include ++#include ++ ++#include ++#include ++#include ++ ++/* This module should depend only on IUP core headers */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#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 ++#include ++ ++#include ++#include ++#include ++#include ++#include ++ ++#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 ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++ ++#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(view); ++ if(!listview) ++ { ++ BView* previous = view; ++ previous->LockLooper(); ++ view = view->ChildAt(0); ++ previous->UnlockLooper(); ++ while(view && !listview) ++ { ++ listview = dynamic_cast(view); ++ view = view->NextSibling(); ++ } ++ } ++ ++ return listview; ++} ++ ++void iupdrvListAppendItem(Ihandle* ih, const char* value) ++{ ++ BView* view = (BView*)ih->handle; ++ ++ BMenuField* menu = dynamic_cast(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(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(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(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(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(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 ++#include ++ ++#include ++#include ++#include ++ ++#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 ++#include ++ ++#include ++#include ++#include ++#include ++#include ++ ++#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((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((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 ++#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 ++#include ++#include ++ ++#include ++#include ++#include ++ ++#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 ++ ++#include ++#include ++#include ++#include ++#include ++ ++#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 ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++#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 ++ ++#include ++#include ++#include ++#include ++#include ++ ++#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(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 ++#include ++#include ++#include ++ ++#include ++#include ++ ++#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 ++ ++#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 ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++ ++#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 ++ ++#include ++#include ++#include ++#include ++#include ++ ++#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 ++ ++#include ++#include ++#include ++#include ++#include ++ ++#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 ++#include ++#include ++ ++#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/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 ++ ++#include ++#include ++#include ++#include ++ ++#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/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/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..76b1a0a 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 +@@ -852,6 +861,7 @@ endif + ifdef USE_IUP + IUP_SUFFIX ?= + ifdef USE_IUP3 ++ ifndef USE_HAIKU + ifdef GTK_DEFAULT + ifdef USE_MOTIF + IUP_SUFFIX := mot +@@ -869,6 +879,7 @@ ifdef USE_IUP + endif + endif + endif ++ endif + else + ifndef NO_OVERRIDE + override USE_MOTIF = Yes +@@ -956,6 +967,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 +1196,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 +