diff -urN qemacs-0.3.3.org/cfb.c qemacs-0.3.3/cfb.c
--- qemacs-0.3.3.org/cfb.c	2013-02-03 13:14:08.057933824 +0100
+++ qemacs-0.3.3/cfb.c	2013-03-08 00:25:33.013107200 +0100
@@ -48,7 +48,7 @@
 static void cfb16_fill_rectangle(QEditScreen *s,
                                  int x1, int y1, int w, int h, QEColor color)
 {
-    CFBContext *cfb = s->private;
+    CFBContext *cfb = s->priv_data;
     unsigned char *dest, *d;
     int y, n;
     unsigned int col;
@@ -99,7 +99,7 @@
 static void cfb32_fill_rectangle(QEditScreen *s,
                                  int x1, int y1, int w, int h, QEColor color)
 {
-    CFBContext *cfb = s->private;
+    CFBContext *cfb = s->priv_data;
     unsigned char *dest, *d;
     int y, n;
     unsigned int col;
@@ -142,7 +142,7 @@
                              int x1, int y1, int w, int h, QEColor color,
                              unsigned char *glyph, int glyph_wrap)
 {
-    CFBContext *cfb = s1->private;
+    CFBContext *cfb = s1->priv_data;
     unsigned char *dest, *d, *s, *src;
     int n;
     unsigned int col;
@@ -186,7 +186,7 @@
                              int x1, int y1, int w, int h, QEColor color,
                              unsigned char *glyph, int glyph_wrap)
 {
-    CFBContext *cfb = s1->private;
+    CFBContext *cfb = s1->priv_data;
     unsigned char *dest, *d, *s, *src;
     int n;
     unsigned int col;
@@ -230,7 +230,7 @@
                            int x_start, int y, const unsigned int *str, int len,
                            QEColor color)
 {
-    CFBContext *cfb = s->private;
+    CFBContext *cfb = s->priv_data;
     GlyphCache *g;
     unsigned char *glyph_ptr;
     int i, x1, y1, x2, y2, wrap, x;
@@ -305,7 +305,7 @@
 int cfb_init(QEditScreen *s, 
              void *base, int wrap, int depth, const char *font_path)
 {
-    CFBContext *cfb = s->private;
+    CFBContext *cfb = s->priv_data;
 
     cfb->base = base;
     cfb->wrap = wrap;
diff -urN qemacs-0.3.3.org/configure qemacs-0.3.3/configure
--- qemacs-0.3.3.org/configure	2013-02-03 13:14:08.001572864 +0100
+++ qemacs-0.3.3/configure	2013-03-08 00:19:41.561250304 +0100
@@ -41,8 +41,10 @@
 esac
 gprof="no"
 network="yes"
+haiku="no"
 win32="no"
 lshared="no"
+dllibs="-ldl"
 extralibs="-lm"
 simpleidct="yes"
 bigendian="no"
@@ -78,6 +80,17 @@
 extralibs="-lpoll -lgnugetopt -lm"
 make="gmake"
 ;;
+Haiku)
+prefix="`finddir B_COMMON_DIRECTORY`"
+# no need for libm, but the network stuff
+extralibs="-lnetwork"
+# dlopen() is in libroot already
+dllibs=""
+# use Haiku GUI; avoid building for X11 even if there are headers around
+haiku="yes"
+x11="no"
+xv="no"
+;;
 *) ;;
 esac
 
@@ -314,6 +327,7 @@
   echo "BUILD_SHARED=yes" >> config.mak
   echo "PIC=-fPIC" >> config.mak
 fi
+echo "DLLIBS=$dllibs" >> config.mak
 echo "EXTRALIBS=$extralibs" >> config.mak
 version=`head $source_path/VERSION`
 echo "VERSION=$version" >>config.mak
@@ -324,6 +338,11 @@
   echo "CONFIG_NETWORK=yes" >> config.mak
 fi
 
+if test "$haiku" = "yes" ; then
+  echo "#define CONFIG_HAIKU 1" >> $TMPH
+  echo "CONFIG_HAIKU=yes" >> config.mak
+fi
+
 if test "$win32" = "yes" ; then
   echo "#define CONFIG_WIN32 1" >> $TMPH
   echo "CONFIG_WIN32=yes" >> config.mak
diff -urN qemacs-0.3.3.org/display.h qemacs-0.3.3/display.h
--- qemacs-0.3.3.org/display.h	2013-02-03 13:14:08.000524288 +0100
+++ qemacs-0.3.3/display.h	2013-03-08 00:23:30.161218560 +0100
@@ -32,7 +32,7 @@
 typedef struct QEFont {
     int ascent;
     int descent;
-    void *private;
+    void *priv_data;
     int system_font; /* TRUE if system font */
     /* cache data */
     int style;
@@ -127,7 +127,7 @@
     /* clip region handling */
     int clip_x1, clip_y1;
     int clip_x2, clip_y2;
-    void *private;
+    void *priv_data;
 };
 
 static inline void draw_text(QEditScreen *s, QEFont *font,
diff -urN qemacs-0.3.3.org/fbfrender.c qemacs-0.3.3/fbfrender.c
--- qemacs-0.3.3.org/fbfrender.c	2013-02-03 13:14:08.061079552 +0100
+++ qemacs-0.3.3/fbfrender.c	2013-03-08 02:16:10.757334016 +0100
@@ -124,7 +124,7 @@
 
 GlyphCache *fbf_decode_glyph1(QEFont *font, int code)
 {
-    UniFontData *uf = font->private;
+    UniFontData *uf = font->priv_data;
     int glyph_index, size, src_width, src_height;
     GlyphCache *glyph_cache;
     GlyphEntry *fbf_glyph_entry;
@@ -269,7 +269,7 @@
             }
         }
     }
-    font->private = uf_found;
+    font->priv_data = uf_found;
     font->ascent = uf_found->ascent;
     font->descent = uf_found->descent;
     return font;
diff -urN qemacs-0.3.3.org/haiku.cpp qemacs-0.3.3/haiku.cpp
--- qemacs-0.3.3.org/haiku.cpp	1970-01-01 01:00:00.000000000 +0100
+++ qemacs-0.3.3/haiku.cpp	2013-03-08 16:13:59.829947904 +0100
@@ -0,0 +1,864 @@
+/*
+ * Haiku driver for QEmacs
+ * Copyright (c) 2013 François Revol.
+ * Copyright (c) 2002 Fabrice Bellard.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+extern "C" {
+//XXX:shouldn't be required anymore
+//#define private priv_data
+#include "qe.h"
+//#undef private
+}
+
+#include <Application.h>
+#include <Font.h>
+#include <String.h>
+#include <View.h>
+#include <Window.h>
+
+extern QEDisplay haiku_dpy;
+
+static int force_tty = 0;
+
+static int font_xsize;
+
+class QEWindow;
+class QEView;
+
+/* state of a single window */
+typedef struct WindowState {
+    BWindow *w;
+    BView *v;
+    BFont font;
+    int events_rd;
+    int events_wr;
+} WindowState;
+
+WindowState haiku_ctx;
+static thread_id bapp_thid;
+static int bapp_ref_count = 0;
+static int events_wr;
+
+static void haiku_handle_event(void *opaque);
+
+static status_t bmessage_input(QEWindow *win, QEView *view, BMessage *message)
+{
+  if (!message)
+    return EINVAL;
+  /* push the message into the pipe */
+  if (write(events_wr, &message, sizeof(BMessage *)) < 0)
+    return errno;
+  return B_OK;
+}
+
+class QEWindow: public BWindow
+{
+public:
+  QEWindow(BRect frame, const char *name, QEView *view)
+  :BWindow(frame, name, B_TITLED_WINDOW, 0)
+  ,fView(view)
+  {}
+
+  virtual ~QEWindow()	{}
+
+//virtual void Show();
+//virtual void Hide();
+//virtual void Minimize(bool minimize);
+virtual bool QuitRequested();
+virtual void DispatchMessage(BMessage *message, BHandler *handler);
+
+private:
+	QEView *fView;
+};
+
+class QEView: public BView
+{
+public:
+  QEView(BRect frame, const char *name);
+  virtual ~QEView();
+
+#if 0
+virtual void	MouseDown(BPoint where);
+virtual void	MouseUp(BPoint where);
+virtual void	MouseMoved(BPoint where, uint32 code, const BMessage *a_message);
+#endif
+virtual void	KeyDown(const char *bytes, int32 numBytes);
+virtual void	KeyUp(const char *bytes, int32 numBytes);
+virtual void	Draw(BRect updateRect);
+#if 0
+virtual void	WindowActivated(bool state);
+virtual void	FrameResized(float new_width, float new_height);
+virtual void	MessageReceived(BMessage *message);
+#endif
+};
+
+
+bool QEWindow::QuitRequested()
+{
+	BMessage *message = new BMessage(B_QUIT_REQUESTED);
+	bmessage_input(this, NULL, message);
+	return false;
+}
+
+void QEWindow::DispatchMessage(BMessage *message, BHandler *handler)
+{
+	uint32 mods;
+	switch (message->what) {
+	case B_KEY_DOWN:
+		if ((message->FindInt32("modifiers", (int32 *)&mods) == B_OK) && 
+				(mods & B_COMMAND_KEY)) {
+			/* BWindow swallows KEY_DOWN when ALT is down...
+			 * so this hack is needed.
+			 */
+			fView->KeyDown(NULL, 0);
+			return;
+		}
+		break;
+	case B_UNMAPPED_KEY_DOWN:
+	case B_UNMAPPED_KEY_UP:
+	case B_KEY_UP:
+		//message->PrintToStream();
+		break;
+	}
+	BWindow::DispatchMessage(message, handler);
+}
+
+QEView::QEView(BRect frame, const char *name)
+	:BView(frame, name, B_FOLLOW_ALL_SIDES, B_WILL_DRAW|B_FRAME_EVENTS)
+{
+	SetViewColor(0,255,0);
+}
+
+QEView::~QEView()
+{
+}
+
+void QEView::KeyDown(const char *bytes, int32 numBytes)
+{
+	BMessage *message = Window()->DetachCurrentMessage();
+  	//message->PrintToStream();
+	bmessage_input(NULL, this, message);
+}
+
+void QEView::KeyUp(const char *bytes, int32 numBytes)
+{
+	uint32 mods;
+	BMessage *message = Window()->DetachCurrentMessage();
+  	//message->PrintToStream();
+	bmessage_input(NULL, this, message);
+}
+
+void QEView::Draw(BRect updateRect)
+{
+	BMessage *message;
+	message = new BMessage(_UPDATE_);
+	message->AddRect("update_rect", updateRect);
+	bmessage_input(NULL, this, message);
+}
+
+
+
+static int haiku_probe(void)
+{
+    if (force_tty)
+        return 0;
+    return 1;
+}
+
+static int32 bapp_quit_thread(void *arg)
+{
+    be_app->Lock();
+    be_app->Quit();
+    return 0;
+}
+
+
+static int32 bapp_thread(void *arg)
+{
+    be_app->Lock();
+    be_app->Run();
+    return 0;
+}
+
+
+
+static void init_application(void)
+{
+    bapp_ref_count++;
+    if (be_app)
+        return; /* done already! */
+    new BApplication("application/x-vnd.Bellard-QEmacs");
+    //new XEmacsApp;
+    bapp_thid = spawn_thread(bapp_thread, "BApplication(QEmacs)", B_NORMAL_PRIORITY, (void *)find_thread(NULL));
+    if (bapp_thid < B_OK)
+        return; /* #### handle errors */
+    if (resume_thread(bapp_thid) < B_OK)
+        return;
+    // This way we ensure we don't create BWindows before be_app is created
+    // (creating it in the thread doesn't ensure this)
+    be_app->Unlock();
+}
+
+static void uninit_application(void)
+{
+	status_t err;
+	if (--bapp_ref_count)
+		return;
+	be_app->Lock();
+	be_app->Quit();
+	//XXX:HACK
+	be_app->Unlock();
+	//be_app_messenger.SendMessage(B_QUIT_REQUESTED);
+	wait_for_thread(bapp_thid, &err);
+	//FIXME:leak or crash
+	//delete be_app;
+	be_app = NULL;
+}
+
+static int haiku_init(QEditScreen *s, int w, int h)
+{
+    int xsize, ysize, font_ysize;
+    WindowState *ctx;
+    
+    if (!be_app) 
+        init_application();
+
+    memcpy(&s->dpy, &haiku_dpy, sizeof(QEDisplay));
+
+	ctx = (WindowState *)malloc(sizeof(WindowState));
+	if (ctx == NULL)
+		return -1;
+    s->priv_data = ctx;
+    s->media = CSS_MEDIA_SCREEN;
+
+	int event_pipe[2];
+	if (pipe(event_pipe) < 0)
+		return -1;
+	fcntl(event_pipe[0], F_SETFD, FD_CLOEXEC);
+	fcntl(event_pipe[1], F_SETFD, FD_CLOEXEC);
+
+	ctx->events_rd = event_pipe[0];
+	ctx->events_wr = events_wr = event_pipe[1];
+
+    set_read_handler(event_pipe[0], haiku_handle_event, s);
+
+
+    ctx->font = BFont(be_fixed_font);
+
+	font_height height;
+	ctx->font.GetHeight(&height);
+
+    font_xsize = (int)ctx->font.StringWidth("n");
+    font_ysize = (int)(height.ascent + height.descent + height.leading);
+
+	if (w == 0)
+		w = 80;
+	if (h == 0)
+		h = 25;
+    xsize = w * font_xsize;
+    ysize = h * font_ysize;
+
+    s->width = xsize;
+    s->height = ysize;
+    s->charset = &charset_utf8;
+
+    s->clip_x1 = 0;
+    s->clip_y1 = 0;
+    s->clip_x2 = s->width;
+    s->clip_y2 = s->height;
+
+	BRect frame(0, 0, s->width - 1, s->height - 1);
+
+	QEView *v = new QEView(frame, "qemacs");
+	ctx->v = v;
+
+	frame.OffsetTo(200, 200);
+
+    ctx->w = new QEWindow(frame, "qemacs", v);
+    ctx->w->AddChild(ctx->v);
+    ctx->v->MakeFocus();
+    ctx->v->SetViewColor(B_TRANSPARENT_COLOR);
+    ctx->v->SetDrawingMode(B_OP_OVER);
+
+    ctx->w->Show();
+    
+    return 0;
+}
+
+static void haiku_close(QEditScreen *s)
+{
+	WindowState *ctx = (WindowState *)s->priv_data;
+	ctx->w->Lock();
+	ctx->w->Quit();
+    free(s->priv_data);
+}
+
+static void haiku_flush(QEditScreen *s)
+{
+}
+
+static int haiku_is_user_input_pending(QEditScreen *s)
+{
+    /* XXX: do it */
+    return 0;
+}
+
+#if 0
+static void push_event(QEEvent *ev)
+{
+    QEEventQ *e;
+    
+    e = malloc(sizeof(QEEventQ));
+    if (!e)
+        return;
+    e->ev = *ev;
+    e->next = NULL;
+    if (!last_event)
+        first_event = e;
+    else
+        last_event->next = e;
+    last_event = e;
+}
+
+static void push_key(int key)
+{
+    QEEvent ev;
+    ev.type = QE_KEY_EVENT;
+    ev.key_event.key = key;
+    push_event(&ev);
+}
+
+static int ignore_wchar_msg = 0;
+
+LRESULT CALLBACK qe_wnd_proc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+    //    printf("msg=%d\n", msg);
+    switch (msg) {
+    case WM_CREATE:
+        /* NOTE: must store them here to avoid problems in main */
+        haiku_ctx.w = hWnd;
+        return 0;
+        
+        /* key handling */
+    case WM_CHAR:
+        if (!ignore_wchar_msg) {
+            push_key(wParam);
+        } else {
+            return DefWindowProc(hWnd, msg, wParam, lParam);
+        }
+        break;
+    case WM_SYSCHAR:
+        if (!ignore_wchar_msg) {
+            int key;
+            key = wParam;
+            if (key >= ' ' && key <= '~') {
+                key = KEY_META(' ') + key - ' ';
+                push_key(key);
+                break;
+            }
+        }
+        return DefWindowProc(hWnd, msg, wParam, lParam);
+    case WM_SYSKEYDOWN:
+    case WM_KEYDOWN:
+        {
+            unsigned int scan;
+            int ctrl, shift, alt, key;
+            
+            ctrl = (GetKeyState(VK_CONTROL) & 0x8000);
+            shift = (GetKeyState(VK_SHIFT) & 0x8000);
+            alt = (GetKeyState(VK_MENU) & 0x8000);
+            
+            ignore_wchar_msg = 0;
+            
+            scan = (unsigned int) ((lParam >> 16) & 0x1FF);
+            switch(scan) {
+            case 0x00E:
+                ignore_wchar_msg = 1;
+                push_key(KEY_BACKSPACE);
+                break;
+            case 0x039: /* space */
+                ignore_wchar_msg = 1;
+                if (!ctrl) 
+                    push_key(KEY_SPC);
+                else
+                    push_key(KEY_CTRL('@'));
+                break;
+            case 0x147: 		       /* home */
+                push_key(KEY_HOME);
+                break;
+            case 0x148:		       /* UP */
+                push_key(KEY_UP);
+                break;
+            case 0x149:		       /* PGUP */
+                push_key(KEY_PAGEUP);
+                break;
+            case 0x14B:		       /* LEFT */
+                push_key(KEY_LEFT);
+                break;
+            case 0x14D:		       /* RIGHT */
+                push_key(KEY_RIGHT);
+                break;
+            case 0x14F:		       /* END */
+                push_key(KEY_END);
+                break;
+            case 0x150:		       /* DOWN */
+                push_key(KEY_DOWN);
+                break;
+            case 0x151:		       /* PGDN */
+                push_key(KEY_PAGEDOWN);
+                break;
+            case 0x153:		       /* DEL */
+                push_key(KEY_DELETE);
+                break;
+            case 0x152:		       /* INSERT */
+                push_key(KEY_INSERT);
+                break;
+            case 0x3b:		       /* F1 */
+            case 0x3c:
+            case 0x3d:
+            case 0x3e:
+            case 0x3f:
+            case 0x40:
+            case 0x41:
+            case 0x42:
+            case 0x43:
+            case 0x44:
+            case 0x57:
+            case 0x58:		       /* F12 */
+                key = scan - 0x3b;
+                if (key > 9)
+                    key -= 0x12;
+                key += KEY_F1;
+                /* we leave Alt-F4 to close the window */
+                if (alt && key == KEY_F4)
+                    return DefWindowProc(hWnd, msg, wParam, lParam);
+                push_key(key);
+                break;
+                  
+            default: 
+                return DefWindowProc(hWnd, msg, wParam, lParam);
+            }
+        }
+        break;
+
+    case WM_KEYUP:
+        ignore_wchar_msg = 0;
+        break;
+          
+    case WM_SYSKEYUP:
+        ignore_wchar_msg = 0;
+        return DefWindowProc(hWnd, msg, wParam, lParam);
+
+    case WM_SIZE:
+	if (wParam != SIZE_MINIMIZED) {
+            QEmacsState *qs = &qe_state;
+            QEEvent ev;
+
+            qs->screen->width = LOWORD(lParam);
+            qs->screen->height = HIWORD(lParam);
+            ev.expose_event.type = QE_EXPOSE_EVENT;
+            push_event(&ev);
+        }
+	break;
+    case WM_PAINT:
+        {
+            PAINTSTRUCT ps;
+            HDC saved_hdc;
+            BeginPaint(haiku_ctx.w, &ps);
+            saved_hdc = haiku_ctx.hdc;
+            haiku_ctx.hdc = ps.hdc;
+            SelectObject(haiku_ctx.hdc, haiku_ctx.font);
+            do_refresh(NULL);
+            
+            EndPaint(haiku_ctx.w, &ps);
+            haiku_ctx.hdc = saved_hdc;
+        }
+	break;
+
+    case WM_SETFOCUS:
+    case WM_KILLFOCUS:
+        break;
+
+    default:
+	return DefWindowProc(hWnd, msg, wParam, lParam);
+    }
+    return 0;
+}
+
+static int get_unicode_key(QEditScreen *s, QEPollData *pd, QEEvent *ev)
+{
+    MSG msg;
+    QEEventQ *e;
+
+    for(;;) {
+        /* check if events queued */
+        if (first_event != NULL) {
+            e = first_event;
+            *ev = e->ev;
+            first_event = e->next;
+            if (!first_event)
+                last_event = NULL;
+            free(e);
+            break;
+        }
+
+        /* check if message queued */
+        if (GetMessage(&msg, NULL, 0, 0)) {
+            TranslateMessage(&msg);
+            DispatchMessage(&msg);
+        }
+    }
+    return 1;
+}
+#endif
+
+/* called when an BMessage is forwarded. dispatch events to qe_handle_event() */
+static void haiku_handle_event(void *opaque)
+{
+    QEditScreen *s = (QEditScreen *)opaque;
+	WindowState *ctx = (WindowState *)s->priv_data;
+    unsigned char buf[16];
+    bigtime_t timestamp_ms;
+    BMessage *event;
+    //fprintf(stderr, "%s()\n", __FUNCTION__);
+/*
+    KeySym keysym;
+*/
+    int shift, ctrl, meta, len, key = 0;
+    QEEvent ev1, *ev = &ev1;
+
+    if (read(ctx->events_rd, &event, sizeof(BMessage *)) < sizeof(BMessage *))
+        return;
+    //event->PrintToStream();
+
+	switch(event->what) {
+	case B_QUIT_REQUESTED:
+		
+		// cancel pending operation
+		ev->key_event.type = QE_KEY_EVENT;
+		ev->key_event.key = KEY_CTRL('g');
+		qe_handle_event(ev);
+
+		// simulate C-x C-c
+		ev->key_event.type = QE_KEY_EVENT;
+		ev->key_event.key = KEY_CTRL('x');
+		qe_handle_event(ev);
+		ev->key_event.type = QE_KEY_EVENT;
+		ev->key_event.key = KEY_CTRL('c');
+		qe_handle_event(ev);
+		break;
+
+	case _UPDATE_:
+		// TODO: flush queued
+		ev->expose_event.type = QE_EXPOSE_EVENT;
+        qe_handle_event(ev);
+		break;
+
+	case B_KEY_UP:
+		break;
+
+	case B_KEY_DOWN:
+	{
+		unsigned int mods = 0;
+		uint32 state;
+		//event->PrintToStream();
+		uint32 scancode;
+		uint32 raw_char;
+		const char *bytes;
+		char buff[6];
+		int numbytes = 0;
+		int i;
+
+		if (event->FindInt64("when", &timestamp_ms) < B_OK)
+			timestamp_ms = 0LL;
+		if (event->FindInt32("modifiers", (int32 *)&state) < B_OK)
+			state = modifiers();
+		if (event->FindInt32("key", (int32 *)&scancode) < B_OK)
+			scancode = 0;
+		if (event->FindInt32("raw_char", (int32 *)&raw_char) < B_OK)
+			raw_char = 0;
+
+		/* check for byte[] first,
+		   because C-space gives bytes="" (and byte[0] = '\0') */
+		for (i = 0; i < 5; i++) {
+			buff[i] = '\0';
+			if (event->FindInt8("byte", i, (int8 *)&buff[i]) < B_OK)
+				break;
+		}
+
+		if (i) {
+			bytes = buff;
+			numbytes = i;
+		} else if (event->FindString("bytes", &bytes) < B_OK)
+			bytes = "";
+
+		if (!numbytes)
+			numbytes = strlen(bytes);
+
+		shift = (state & B_SHIFT_KEY);
+        ctrl = (state & B_CONTROL_KEY);
+        meta = (state & (B_LEFT_OPTION_KEY | B_COMMAND_KEY));
+
+        //fprintf(stderr, "%cshift %cctrl %cmeta numbytes %d \n", shift ? ' ' : '!', ctrl ? ' ' : '!', meta ? ' ' : '!', numbytes);
+
+		char byte = 0;
+		if (numbytes == 1) {
+			byte = bytes[0];
+			if (state & B_CONTROL_KEY)
+				byte = (char)raw_char;
+			switch (byte) {
+				case B_BACKSPACE:
+					key = KEY_BACKSPACE;
+					if (meta)
+						key = KEY_META(KEY_BACKSPACE);
+					break;
+				case B_TAB:
+					key = KEY_TAB;
+					break;
+				case B_ENTER:
+					key = KEY_RET;
+					break;
+				case B_ESCAPE:
+					key = KEY_ESC;
+					break;
+				case B_SPACE:
+					key = KEY_SPC;
+					break;
+				case B_DELETE:
+					key = KEY_DELETE;
+					break;
+				case B_INSERT:
+					key = KEY_INSERT;
+					break;
+				case B_HOME:
+					key = ctrl ? KEY_CTRL_HOME : KEY_HOME;
+					break;
+				case B_END:
+					key = ctrl ? KEY_CTRL_END : KEY_END;
+					break;
+				case B_PAGE_UP:
+					key = KEY_PAGEUP;
+					break;
+				case B_PAGE_DOWN:
+					key = KEY_PAGEDOWN;
+					break;
+				case B_LEFT_ARROW:
+					key = ctrl ? KEY_CTRL_LEFT : KEY_LEFT;
+					break;
+				case B_RIGHT_ARROW:
+					key = ctrl ? KEY_CTRL_RIGHT : KEY_RIGHT;
+					break;
+				case B_UP_ARROW:
+					key = KEY_UP;
+					break;
+				case B_DOWN_ARROW:
+					key = KEY_DOWN;
+					break;
+				case B_FUNCTION_KEY:
+					switch (scancode) {
+						case B_F1_KEY:
+						case B_F2_KEY:
+						case B_F3_KEY:
+						case B_F4_KEY:
+						case B_F5_KEY:
+						case B_F6_KEY:
+						case B_F7_KEY:
+						case B_F8_KEY:
+						case B_F9_KEY:
+						case B_F10_KEY:
+						case B_F11_KEY:
+						case B_F12_KEY:
+							key = KEY_F1 + scancode - B_F1_KEY;
+							break;
+						case B_PRINT_KEY:
+						case B_SCROLL_KEY:
+						case B_PAUSE_KEY:
+						default:
+							break;
+					}
+					break;
+				case 0:
+					break;
+				default:
+					if (byte >= ' ' && byte <= '~')
+						if (meta)
+							key = KEY_META(' ') + byte - ' ';
+						else if (ctrl)
+							key = KEY_CTRL(byte);
+						else
+							key = byte;
+
+			}
+	    } else {
+	    	const char *p = bytes;
+	    	key = utf8_decode(&p);
+	    }
+
+		got_key:
+		if (key) {
+			ev->key_event.type = QE_KEY_EVENT;
+			ev->key_event.key = key;
+			qe_handle_event(ev);
+		}
+	}
+		break;
+	}
+
+	delete event;
+}
+
+static void haiku_fill_rectangle(QEditScreen *s,
+                               int x1, int y1, int w, int h, QEColor color)
+{
+	WindowState *ctx = (WindowState *)s->priv_data;
+	//fprintf(stderr, "%s()\n", __FUNCTION__);
+
+   /* XXX: suppress XOR mode */
+   if (color == QECOLOR_XOR)
+       color = QERGB(0xff, 0xff, 0xff);
+
+	BRect r(x1, y1, x1 + w - 1, y1 + h - 1);
+	rgb_color c = {(color >> 16) & 0xff, (color >> 8) & 0xff, color & 0xff,
+		0xff};
+
+	ctx->v->LockLooper();
+
+	ctx->v->SetHighColor(c);
+	ctx->v->FillRect(r);
+	
+	ctx->v->UnlockLooper();
+}
+
+static QEFont *haiku_open_font(QEditScreen *s, int style, int size)
+{
+	WindowState *ctx = (WindowState *)s->priv_data;
+	//fprintf(stderr, "%s()\n", __FUNCTION__);
+    QEFont *font;
+
+    font = (QEFont *)malloc(sizeof(QEFont));
+    if (!font)
+        return NULL;
+
+    // TODO: use style / size
+    BFont *f = new BFont(ctx->font);
+
+	font_height height;
+    f->GetHeight(&height);
+    font->ascent = (int)height.ascent;
+    font->descent = (int)(height.descent + height.leading);
+    font->priv_data = f;
+    return font;
+}
+
+static void haiku_close_font(QEditScreen *s, QEFont *font)
+{
+	BFont *f = (BFont *)font->priv_data;
+	delete f;
+    free(font);
+}
+
+static void haiku_text_metrics(QEditScreen *s, QEFont *font, 
+                             QECharMetrics *metrics,
+                             const unsigned int *str, int len)
+{
+	//TODO: use BFont::GetEscapements() or StringWidth()
+    int i, x;
+    metrics->font_ascent = font->ascent;
+    metrics->font_descent = font->descent;
+    x = 0;
+    for(i=0;i<len;i++)
+        x += font_xsize;
+    metrics->width = x;
+}
+
+static void haiku_draw_text(QEditScreen *s, QEFont *font,
+                          int x1, int y, const unsigned int *str, int len,
+                          QEColor color)
+{
+	WindowState *ctx = (WindowState *)s->priv_data;
+	BFont *f = (BFont *)(font->priv_data);
+    int i;
+	//fprintf(stderr, "%s()\n", __FUNCTION__);
+
+   /* XXX: suppress XOR mode */
+   if (color == QECOLOR_XOR)
+       color = QERGB(0xff, 0xff, 0xff);
+
+	rgb_color c = {(color >> 16) & 0xff, (color >> 8) & 0xff, color & 0xff,
+		0xff};
+
+	ctx->v->LockLooper();
+
+	ctx->v->SetHighColor(c);
+	ctx->v->SetLowColor(B_TRANSPARENT_COLOR);
+	ctx->v->SetFont(f);
+	ctx->v->MovePenTo(x1, y - 1);
+
+    char buf[10];
+    unsigned int cc;
+
+	BString text;
+    for(i=0;i<len;i++) {
+    	cc = str[i];
+    	unicode_to_charset((unsigned char *)buf, cc, &charset_utf8);
+    	text << buf;
+		//ctx->v->DrawString(buf);
+    }
+	ctx->v->DrawString(text.String());
+	
+	ctx->v->UnlockLooper();
+
+    //TextOutW(haiku_ctx.hdc, x1, y - font->ascent, buf, len);
+}
+
+static void haiku_set_clip(QEditScreen *s,
+                         int x, int y, int w, int h)
+{
+    /* nothing to do */
+}
+
+extern QEDisplay haiku_dpy = {
+    "haiku",
+    haiku_probe,
+    haiku_init,
+    haiku_close,
+    NULL,
+    haiku_flush,
+    haiku_is_user_input_pending,
+    haiku_fill_rectangle,
+    haiku_open_font,
+    haiku_close_font,
+    haiku_text_metrics,
+    haiku_draw_text,
+    haiku_set_clip,
+    NULL, /* no selection handling */
+    NULL, /* no selection handling */
+};
+
+static CmdOptionDef cmd_options[] = {
+    { "nw", NULL, CMD_OPT_BOOL, "force tty terminal usage", 
+      {int_ptr: &force_tty} },
+    { NULL },
+};
+
+int haiku_init(void)
+{
+    qe_register_cmd_line_options(cmd_options);
+    return qe_register_display(&haiku_dpy);
+}
+
+qe_module_init(haiku_init);
diff -urN qemacs-0.3.3.org/html2png.c qemacs-0.3.3/html2png.c
--- qemacs-0.3.3.org/html2png.c	2013-02-03 13:14:08.063700992 +0100
+++ qemacs-0.3.3/html2png.c	2013-03-08 00:28:58.506462208 +0100
@@ -101,7 +101,7 @@
 /* realloc ppm bitmap */
 int ppm_resize(QEditScreen *s, int w, int h)
 {
-    CFBContext *cfb = s->private;
+    CFBContext *cfb = s->priv_data;
     unsigned char *data;
     
     /* alloc bitmap */
@@ -131,7 +131,7 @@
     if (!cfb)
         return -1;
 
-    s->private = cfb;
+    s->priv_data = cfb;
     s->media = CSS_MEDIA_SCREEN;
 
     if (cfb_init(s, NULL, w * sizeof(int), 32, ".") < 0)
@@ -147,7 +147,7 @@
 
 static void ppm_close(QEditScreen *s)
 {
-    CFBContext *cfb = s->private;
+    CFBContext *cfb = s->priv_data;
     
     free(cfb->base);
     free(cfb);
@@ -155,7 +155,7 @@
 
 int ppm_save(QEditScreen *s, const char *filename)
 {
-    CFBContext *cfb = s->private;
+    CFBContext *cfb = s->priv_data;
     int w, h, x, y;
     unsigned int r, g, b, v;
     unsigned int *data;
@@ -190,7 +190,7 @@
 
 int png_save(QEditScreen *s, const char *filename)
 {
-    CFBContext *cfb = s->private;
+    CFBContext *cfb = s->priv_data;
     png_struct * volatile png_ptr = NULL;
     png_info * volatile info_ptr = NULL;
     png_byte *row_ptr, *row_pointers[1], *row = NULL;
diff -urN qemacs-0.3.3.org/Makefile qemacs-0.3.3/Makefile
--- qemacs-0.3.3.org/Makefile	2013-02-03 13:14:08.000524288 +0100
+++ qemacs-0.3.3/Makefile	2013-03-08 02:17:54.859570176 +0100
@@ -45,11 +45,11 @@
 endif
 
 ifdef CONFIG_DLL
-LIBS+=-ldl
+LIBS+=$(DLLIBS)
 # export some qemacs symbols
 LDFLAGS+=-Wl,-E
 endif
-LIBS+=-lm
+LIBS+=$(EXTRALIBS)
 
 TARGETS+=qe$(EXE) qe-doc.html
 
@@ -64,6 +64,11 @@
 OBJS+= shell.o dired.o 
 endif
 
+ifdef CONFIG_HAIKU
+OBJS+= haiku.o
+LIBS+= -lbe
+endif
+
 ifdef CONFIG_WIN32
 OBJS+= win32.o
 LIBS+= -lgdi32
@@ -155,15 +160,17 @@
 	rm -f config.h config.mak
 
 install: qe qe.1 kmaps ligatures html2png
-	install -m 755 qe $(prefix)/bin/qemacs
-	ln -sf qemacs $(prefix)/bin/qe
+	mkdir -p $(DESTDIR)$(prefix)/bin
+	install -m 755 qe $(DESTDIR)$(prefix)/bin/qemacs
+	ln -sf qemacs $(DESTDIR)$(prefix)/bin/qe
 ifdef CONFIG_FFMPEG
-	ln -sf qemacs $(prefix)/bin/ffplay
+	ln -sf qemacs $(DESTDIR)$(prefix)/bin/ffplay
 endif
-	mkdir -p $(prefix)/share/qe
-	install kmaps ligatures $(prefix)/share/qe
-	install qe.1 $(prefix)/man/man1
-	install -m 755 -s html2png $(prefix)/bin
+	mkdir -p $(DESTDIR)$(prefix)/share/qe
+	install kmaps ligatures $(DESTDIR)$(prefix)/share/qe
+	mkdir -p $(DESTDIR)$(prefix)/man/man1
+	install qe.1 $(DESTDIR)$(prefix)/man/man1
+	install -m 755 -s html2png $(DESTDIR)$(prefix)/bin
 
 TAGS: force
 	etags *.[ch]
@@ -244,7 +251,7 @@
       Russian.kmap SGML.kmap TeX.kmap Troff.kmap VNtelex.kmap \
       Vietnamese.kmap XKB_iso8859-4.kmap
 #     Hangul.kmap Hangul2.kmap Hangul3.kmap Unicode2.kmap 
-KMAPS_DIR=$(prefix)/share/yudit/data
+KMAPS_DIR=$(DESTDIR)$(prefix)/share/yudit/data
 KMAPS:=$(addprefix $(KMAPS_DIR)/, $(KMAPS))
 
 kmaptoqe: kmaptoqe.c
diff -urN qemacs-0.3.3.org/tty.c qemacs-0.3.3/tty.c
--- qemacs-0.3.3.org/tty.c	2013-02-03 13:14:08.002621440 +0100
+++ qemacs-0.3.3/tty.c	2013-03-09 00:45:31.432275456 +0100
@@ -150,7 +150,7 @@
 
     tty_screen = s;
     ts = &tty_state;
-    s->private = ts;
+    s->priv_data = ts;
     s->media = CSS_MEDIA_TTY;
 
     tcgetattr (0, &tty);
@@ -214,7 +214,7 @@
 static void term_exit(void)
 {
     QEditScreen *s = tty_screen;
-    TTYState *ts = s->private;
+    TTYState *ts = s->priv_data;
 
     tcsetattr (0, TCSANOW, &ts->oldtty);
 }
@@ -222,7 +222,7 @@
 static void tty_resize(int sig)
 {
     QEditScreen *s = tty_screen;
-    TTYState *ts = s->private;
+    TTYState *ts = s->priv_data;
     int size;
 
     if (sig == -1) {
@@ -254,7 +254,7 @@
 
 static void term_cursor_at(QEditScreen *s, int x1, int y1, int w, int h)
 {
-    TTYState *ts = s->private;
+    TTYState *ts = s->priv_data;
     ts->cursor_x = x1;
     ts->cursor_y = y1;
 }
@@ -277,7 +277,7 @@
 static void tty_read_handler(void *opaque)
 {
     QEditScreen *s = opaque;
-    TTYState *ts = s->private;
+    TTYState *ts = s->priv_data;
     int ch;
     QEEvent ev1, *ev = &ev1;
 
@@ -312,6 +312,7 @@
             ts->input_param = 0;
         } else if (ch == 'O') {
             ts->input_state = IS_ESC2;
+            ts->input_param = 0;
         } else {
             ch = KEY_META(ch);
             ts->input_state = IS_NORM;
@@ -347,13 +348,26 @@
         break;
     case IS_ESC2:
         /* xterm fn */
-        ts->input_state = IS_NORM;
-        if (ch >= 'P' && ch <= 'S') {
-            ch = KEY_F1 + ch - 'P';
-        the_end:
-            ev->key_event.type = QE_KEY_EVENT;
-            ev->key_event.key = ch;
-            qe_handle_event(ev);
+        if (!isdigit(ch)) {
+            ts->input_state = IS_NORM;
+            if (ts->input_param == 5 && ch >= 'A' && ch <= 'D') {
+                /* CTRL-arrows variant */
+                ch += 'a' - 'A';
+                ch = KEY_ESC1(ch);
+                goto the_end;
+            } else if (ch >= 'A' && ch <= 'D') {
+                /* arrows variant */
+                ch = KEY_ESC1(ch);
+                goto the_end;
+            } else if (ch >= 'P' && ch <= 'S') {
+                ch = KEY_F1 + ch - 'P';
+            the_end:
+                ev->key_event.type = QE_KEY_EVENT;
+                ev->key_event.key = ch;
+                qe_handle_event(ev);
+            }
+        } else {
+        	ts->input_param = ts->input_param * 10 + ch - '0';
         }
         break;
     }
@@ -399,7 +413,7 @@
 static void term_fill_rectangle(QEditScreen *s,
                                 int x1, int y1, int w, int h, QEColor color)
 {
-    TTYState *ts = s->private;
+    TTYState *ts = s->priv_data;
     int x2 = x1 + w;
     int y2 = y1 + h;
     int x, y;
@@ -443,7 +457,7 @@
         return NULL;
     font->ascent = 0;
     font->descent = 1;
-    font->private = NULL;
+    font->priv_data = NULL;
     return font;
 }
 
@@ -493,7 +507,7 @@
                            int x, int y, const unsigned int *str, int len,
                            QEColor color)
 {
-    TTYState *ts = s->private;
+    TTYState *ts = s->priv_data;
     TTYChar *ptr;
     int fgcolor, w, n;
     unsigned int cc;
@@ -560,7 +574,7 @@
 
 static void term_flush(QEditScreen *s)
 {
-    TTYState *ts = s->private;
+    TTYState *ts = s->priv_data;
     TTYChar *ptr, *optr;
     int x, y, bgcolor, fgcolor;
     char buf[10];
diff -urN qemacs-0.3.3.org/win32.c qemacs-0.3.3/win32.c
--- qemacs-0.3.3.org/win32.c	2013-02-03 13:14:08.000000000 +0100
+++ qemacs-0.3.3/win32.c	2013-03-08 00:24:37.173277184 +0100
@@ -139,7 +139,7 @@
 
     memcpy(&s->dpy, &win32_dpy, sizeof(QEDisplay));
 
-    s->private = NULL;
+    s->priv_data = NULL;
     s->media = CSS_MEDIA_SCREEN;
     
     win_ctx.font = CreateFont(-12, 0, 0, 0, 0 , 0, 0, 0, 0, 0, 0, 0, 
@@ -434,7 +434,7 @@
     GetTextMetrics(win_ctx.hdc, &tm);
     font->ascent = tm.tmAscent;
     font->descent = tm.tmDescent;
-    font->private = NULL;
+    font->priv_data = NULL;
     return font;
 }
 
diff -urN qemacs-0.3.3.org/x11.c qemacs-0.3.3/x11.c
--- qemacs-0.3.3.org/x11.c	2013-02-03 13:14:08.060817408 +0100
+++ qemacs-0.3.3/x11.c	2013-03-08 00:24:24.825491456 +0100
@@ -191,7 +191,7 @@
 
     memcpy(&s->dpy, &x11_dpy, sizeof(QEDisplay));
 
-    s->private = NULL;
+    s->priv_data = NULL;
     s->media = CSS_MEDIA_SCREEN;
 
     display = XOpenDisplay(display_str);
@@ -552,13 +552,13 @@
                              0);
     font->ascent = renderFont->ascent;
     font->descent = renderFont->descent;
-    font->private = renderFont;
+    font->priv_data = renderFont;
     return font;
 }
 
 static void term_close_font(QEditScreen *s, QEFont *font)
 {
-    XftFont *renderFont = font->private;
+    XftFont *renderFont = font->priv_data;
 
     XftFontClose(display, renderFont);
     free(font);
@@ -566,7 +566,7 @@
 
 static int term_glyph_width(QEditScreen *s, QEFont *font, unsigned int cc)
 {
-    XftFont *renderFont = font->private;
+    XftFont *renderFont = font->priv_data;
     XGlyphInfo gi;
 
     XftTextExtents32 (display, renderFont, &cc, 1, &gi);
@@ -577,7 +577,7 @@
                            int x, int y, const unsigned int *str, int len,
                            QEColor color)
 {
-    XftFont *renderFont = font->private;
+    XftFont *renderFont = font->priv_data;
     XftColor col;
     int r, g, b, a;
     
@@ -749,7 +749,7 @@
 
     font->ascent = xfont->ascent;
     font->descent = xfont->descent;
-    font->private = xfont;
+    font->priv_data = xfont;
     return font;
  fail:
     XFreeFontNames(list);
@@ -759,7 +759,7 @@
 
 static void term_close_font(QEditScreen *s, QEFont *font)
 {
-    XFontStruct *xfont = font->private;
+    XFontStruct *xfont = font->priv_data;
 
     XFreeFont(display, xfont);
     free(font);
@@ -769,7 +769,7 @@
    associated. */
 static XCharStruct *get_char_struct(QEFont *font, int cc)
 {
-    XFontStruct *xfont = font->private;
+    XFontStruct *xfont = font->priv_data;
     int b1, b2;
     XCharStruct *cs;
 
@@ -811,7 +811,7 @@
 static XCharStruct *handle_fallback(QEditScreen *s, QEFont **out_font, 
                                     QEFont *font, unsigned int cc)
 {
-    XFontStruct *xfont = font->private;
+    XFontStruct *xfont = font->priv_data;
     XCharStruct *cs;
     int fallback_count;
     QEFont *font1;
@@ -833,7 +833,7 @@
     }
     
     /* really no glyph : use default char in current font */
-    xfont = font->private;
+    xfont = font->priv_data;
     cs = get_char_struct(font, xfont->default_char);
     *out_font = font;
     return cs;
@@ -904,13 +904,13 @@
             cs = handle_fallback(s, &font1, font, cc);
             if (!cs) {
                 /* still no char: use default glyph */
-                xfont = font->private;
+                xfont = font->priv_data;
                 cc = xfont->default_char;
             }
         }
         /* flush previous chars if font change needed */
         if (font1 != last_font && q > x11_str) {
-            xfont = last_font->private;
+            xfont = last_font->priv_data;
             l = q - x11_str;
             XSetFont(display, gc, xfont->fid);
             XDrawString16(display, dbuffer, gc,
@@ -927,7 +927,7 @@
     }
     if (q > x11_str) {
         /* flush remaining chars (more common case) */
-        xfont = last_font->private;
+        xfont = last_font->priv_data;
         l = q - x11_str;
         XSetFont(display, gc, xfont->fid);
         XDrawString16(display, dbuffer, gc,
