Index: Makefile
===================================================================
RCS file: /sources/qemacs/qemacs/Makefile,v
retrieving revision 1.50
diff -u -r1.50 Makefile
--- qemacs-0.3.2dev-cvs/Makefile	5 Jun 2008 07:14:12 -0000	1.50
+++ qemacs-0.3.2dev-cvs/Makefile	14 Mar 2013 23:32:46 -0000
@@ -63,7 +63,7 @@
 endif
 
 ifdef CONFIG_DLL
-  LIBS+=-ldl
+  LIBS+=$(DLLIBS)
   # export some qemacs symbols
   LDFLAGS+=-Wl,-E
 endif
@@ -72,6 +72,11 @@
   TARGETS+= qe-doc.html
 endif
 
+ifdef CONFIG_HAIKU
+  OBJS+= haiku.o
+  LIBS+= -lbe
+endif
+
 ifdef CONFIG_WIN32
   OBJS+= unix.o
   TOBJS+= unix.o
@@ -84,7 +89,7 @@
 else
   OBJS+= unix.o tty.o
   TOBJS+= unix.o tty.o
-  LIBS+= -lm
+  LIBS+= $(EXTRALIBS)
 endif
 
 ifdef CONFIG_QSCRIPT
@@ -143,7 +148,7 @@
   OBJS+= video.o image.o
   DEP_LIBS+= $(FFMPEG_LIBDIR)/libavcodec/libavcodec.a $(FFMPEG_LIBDIR)/libavformat/libavformat.a
   LIBS+= -L$(FFMPEG_LIBDIR)/libavcodec -L$(FFMPEG_LIBDIR)/libavformat -lavformat -lavcodec -lz -lpthread
-  DEFINES+= -I$(FFMPEG_SRCDIR)/libavcodec -I$(FFMPEG_SRCDIR)/libavformat
+  DEFINES+= -I$(FFMPEG_SRCDIR) -I$(FFMPEG_SRCDIR)/libavcodec -I$(FFMPEG_SRCDIR)/libavformat
   TARGETS+= ffplay$(EXE)
 endif
 
@@ -226,6 +231,9 @@
 $(OBJS_DIR)/%.o: %.c qe.h qestyles.h config.h config.mak Makefile
 	$(CC) $(DEFINES) $(CFLAGS) -o $@ -c $<
 
+$(OBJS_DIR)/haiku.o: haiku.cpp qe.h qestyles.h config.h config.mak Makefile
+	g++ $(DEFINES) $(CFLAGS) -Wno-multichar -o $@ -c $<
+
 #
 # Test for bidir algorithm
 #
@@ -391,7 +399,8 @@
        charsetjis.def charsetmore.c clang.c config.eg config.h      \
        configure cptoqe.c cutils.c cutils.h dired.c display.c       \
        display.h docbook.c extras.c fbffonts.c fbfrender.c          \
-       fbfrender.h fbftoqe.c hex.c html.c html2png.c htmlsrc.c      \
+       fbfrender.h fbftoqe.c haiku.cpp hex.c html.c html2png.c      \
+       htmlsrc.c      \
        image.c indic.c input.c jistoqe.c kmap.c kmaptoqe.c          \
        latex-mode.c libfbf.c libfbf.h ligtoqe.c list.c makemode.c   \
        mpeg.c perl.c qe-doc.html qe-doc.texi qe.1 qe.c qe.h qe.tcc  \
Index: cfb.c
===================================================================
RCS file: /sources/qemacs/qemacs/cfb.c,v
retrieving revision 1.8
diff -u -r1.8 cfb.c
--- qemacs-0.3.2dev-cvs/cfb.c	8 Apr 2008 06:55:44 -0000	1.8
+++ qemacs-0.3.2dev-cvs/cfb.c	14 Mar 2013 23:32:46 -0000
@@ -50,7 +50,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;
@@ -101,7 +101,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;
@@ -145,7 +145,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;
@@ -189,7 +189,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;
@@ -233,7 +233,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;
@@ -309,7 +309,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;
Index: configure
===================================================================
RCS file: /sources/qemacs/qemacs/configure,v
retrieving revision 1.15
diff -u -r1.15 configure
--- qemacs-0.3.2dev-cvs/configure	17 Apr 2008 15:06:44 -0000	1.15
+++ qemacs-0.3.2dev-cvs/configure	14 Mar 2013 23:32:46 -0000
@@ -45,9 +45,11 @@
 ptsname="yes"
 gprof="no"
 network="yes"
+haiku="no"
 win32="no"
 cygwin="no"
 lshared="no"
+dllibs="-ldl"
 extralibs=""
 simpleidct="yes"
 bigendian="no"
@@ -79,10 +81,10 @@
     # no need for libm, but the inet stuff
     # Check for BONE
     if (echo $BEINCLUDES|grep 'headers/be/bone' >/dev/null); then
-        extralibs="-lbind -lsocket -lm"
+        extralibs="-lbind -lsocket"
     else
         echo "Not sure building for net_server will succeed... good luck."
-        extralibs="-lsocket -lm"
+        extralibs="-lsocket"
     fi
     ;;
   BSD/OS)
@@ -102,6 +104,19 @@
   CYGWIN*)
     cygwin="yes"
     ;;
+  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"
+    html="yes"
+    png="yes"
+    x11="no"
+    xv="no"
+    ;;
   *)
     extralibs="-lm"
     unlockio="yes"
@@ -256,8 +271,11 @@
 if test "$x11" = "no" ; then
     xv="no"
     xrender="no"
-    png="no"
+fi
+
+if test "$x11" = "no" -a "$haiku" = "no" ; then
     ffmpeg="no"
+    png="no"
     html="no"
 fi
 
@@ -439,6 +457,7 @@
   echo "BUILD_SHARED=yes" >> config.mak
   echo "PIC=-fPIC" >> config.mak
 fi
+echo "DLLIBS=$dllibs" >> config.mak
 echo "EXTRALIBS=$extralibs" >> config.mak
 echo -n "VERSION=" >>config.mak
 echo -n `head $source_path/VERSION` >> config.mak
@@ -451,6 +470,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
Index: display.h
===================================================================
RCS file: /sources/qemacs/qemacs/display.h,v
retrieving revision 1.11
diff -u -r1.11 display.h
--- qemacs-0.3.2dev-cvs/display.h	11 Jan 2008 11:29:28 -0000	1.11
+++ qemacs-0.3.2dev-cvs/display.h	14 Mar 2013 23:32:46 -0000
@@ -53,7 +53,7 @@
     int refcount;
     int ascent;
     int descent;
-    void *private;
+    void *priv_data;
     int system_font; /* TRUE if system font */
     /* cache data */
     int style;
@@ -148,12 +148,12 @@
     QECharset *charset; /* the charset of the TTY, XXX: suppress that,
                           use a system in fonts instead */
     int media; /* media type (see CSS_MEDIA_xxx) */
-    int bitmap_format; /* supported bitmap format */
-    int video_format; /* supported video format */
+    QEBitmapFormat bitmap_format; /* supported bitmap format */
+    QEBitmapFormat video_format; /* supported video format */
     /* clip region handling */
     int clip_x1, clip_y1;
     int clip_x2, clip_y2;
-    void *private;
+    void *priv_data;
 };
 
 int qe_register_display(QEDisplay *dpy);
Index: fbfrender.c
===================================================================
RCS file: /sources/qemacs/qemacs/fbfrender.c,v
retrieving revision 1.10
diff -u -r1.10 fbfrender.c
--- qemacs-0.3.2dev-cvs/fbfrender.c	8 Jan 2008 16:37:54 -0000	1.10
+++ qemacs-0.3.2dev-cvs/fbfrender.c	14 Mar 2013 23:32:46 -0000
@@ -124,7 +124,7 @@
 
 static 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;
@@ -270,7 +270,7 @@
             }
         }
     }
-    font->private = uf_found;
+    font->priv_data = uf_found;
     font->ascent = uf_found->ascent;
     font->descent = uf_found->descent;
     return font;
Index: html2png.c
===================================================================
RCS file: /sources/qemacs/qemacs/html2png.c,v
retrieving revision 1.12
diff -u -r1.12 html2png.c
--- qemacs-0.3.2dev-cvs/html2png.c	11 Jan 2008 11:29:28 -0000	1.12
+++ qemacs-0.3.2dev-cvs/html2png.c	14 Mar 2013 23:32:47 -0000
@@ -135,7 +135,7 @@
 /* realloc ppm bitmap */
 static int ppm_resize(QEditScreen *s, int w, int h)
 {
-    CFBContext *cfb = s->private;
+    CFBContext *cfb = s->priv_data;
 
     /* alloc bitmap */
     if (!qe_realloc(&cfb->base, w * h * sizeof(int))) {
@@ -160,7 +160,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)
@@ -169,7 +169,7 @@
     if (ppm_resize(s, w, h) < 0) {
     fail:
         qe_free(&cfb->base);
-        qe_free(&s->private);
+        qe_free(&s->priv_data);
         return -1;
     }
     return 0;
@@ -177,15 +177,15 @@
 
 static void ppm_close(QEditScreen *s)
 {
-    CFBContext *cfb = s->private;
+    CFBContext *cfb = s->priv_data;
 
     qe_free(&cfb->base);
-    qe_free(&s->private);
+    qe_free(&s->priv_data);
 }
 
 static 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;
@@ -219,7 +219,7 @@
 
 static int png_save(QEditScreen *s, const char *filename)
 {
-    CFBContext *cfb = s->private;
+    CFBContext *cfb = s->priv_data;
     struct png_save_data {
         FILE *f;
         png_structp png_ptr;
Index: qe.h
===================================================================
RCS file: /sources/qemacs/qemacs/qe.h,v
retrieving revision 1.96
diff -u -r1.96 qe.h
--- qemacs-0.3.2dev-cvs/qe.h	4 May 2008 15:54:39 -0000	1.96
+++ qemacs-0.3.2dev-cvs/qe.h	14 Mar 2013 23:32:48 -0000
@@ -267,11 +267,11 @@
 int ustristart(const unsigned int *str, const char *val, const unsigned int **ptr);
 static inline unsigned int *umemmove(unsigned int *dest,
                                      unsigned int *src, int count) {
-    return memmove(dest, src, count * sizeof(unsigned int));
+    return (unsigned int *)memmove(dest, src, count * sizeof(unsigned int));
 }
 static inline unsigned int *umemcpy(unsigned int *dest,
                                     unsigned int *src, int count) {
-    return memcpy(dest, src, count * sizeof(unsigned int));
+    return (unsigned int *)memcpy(dest, src, count * sizeof(unsigned int));
 }
 int umemcmp(const unsigned int *s1, const unsigned int *s2, int count);
 
Index: tty.c
===================================================================
RCS file: /sources/qemacs/qemacs/tty.c,v
retrieving revision 1.50
diff -u -r1.50 tty.c
--- qemacs-0.3.2dev-cvs/tty.c	23 Apr 2008 15:30:33 -0000	1.50
+++ qemacs-0.3.2dev-cvs/tty.c	14 Mar 2013 23:32:49 -0000
@@ -118,7 +118,7 @@
 
     tty_screen = s;
     ts = &tty_state;
-    s->private = ts;
+    s->priv_data = ts;
     s->media = CSS_MEDIA_TTY;
 
     /* Derive some settings from the TERM environment variable */
@@ -263,7 +263,7 @@
 static void tty_term_exit(void)
 {
     QEditScreen *s = tty_screen;
-    TTYState *ts = s->private;
+    TTYState *ts = s->priv_data;
 
     tcsetattr(fileno(s->STDIN), TCSANOW, &ts->oldtty);
 }
@@ -271,7 +271,7 @@
 static void tty_resize(__unused__ int sig)
 {
     QEditScreen *s = tty_screen;
-    TTYState *ts = s->private;
+    TTYState *ts = s->priv_data;
     struct winsize ws;
     int i, count, size;
     TTYChar tc;
@@ -318,7 +318,7 @@
 static void tty_term_cursor_at(QEditScreen *s, int x1, int y1,
                                __unused__ int w, __unused__ int h)
 {
-    TTYState *ts = s->private;
+    TTYState *ts = s->priv_data;
     ts->cursor_x = x1;
     ts->cursor_y = y1;
 }
@@ -380,7 +380,7 @@
 {
     QEditScreen *s = opaque;
     QEmacsState *qs = &qe_state;
-    TTYState *ts = s->private;
+    TTYState *ts = s->priv_data;
     int ch;
     QEEvent ev1, *ev = &ev1;
 
@@ -425,6 +425,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;
@@ -826,7 +827,7 @@
 static void tty_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;
@@ -869,7 +870,7 @@
 
     font->ascent = 0;
     font->descent = 1;
-    font->private = NULL;
+    font->priv_data = NULL;
     return font;
 }
 
@@ -958,7 +959,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;
@@ -1021,7 +1022,7 @@
 
 static void tty_term_flush(QEditScreen *s)
 {
-    TTYState *ts = s->private;
+    TTYState *ts = s->priv_data;
     TTYChar *ptr, *ptr1, *ptr2, *ptr3, *ptr4, cc, blankcc;
     int y, shadow, ch, bgcolor, fgcolor, shifted;
 
Index: win32.c
===================================================================
RCS file: /sources/qemacs/qemacs/win32.c,v
retrieving revision 1.15
diff -u -r1.15 win32.c
--- qemacs-0.3.2dev-cvs/win32.c	23 Apr 2008 15:29:35 -0000	1.15
+++ qemacs-0.3.2dev-cvs/win32.c	14 Mar 2013 23:32:49 -0000
@@ -139,7 +139,7 @@
     if (!_hPrev)
         init_application();
 
-    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,
@@ -452,7 +452,7 @@
     GetTextMetrics(win_ctx.hdc, &tm);
     font->ascent = tm.tmAscent;
     font->descent = tm.tmDescent;
-    font->private = NULL;
+    font->priv_data = NULL;
     return font;
 }
 
Index: x11.c
===================================================================
RCS file: /sources/qemacs/qemacs/x11.c,v
retrieving revision 1.28
diff -u -r1.28 x11.c
--- qemacs-0.3.2dev-cvs/x11.c	15 Apr 2008 23:24:04 -0000	1.28
+++ qemacs-0.3.2dev-cvs/x11.c	14 Mar 2013 23:32:49 -0000
@@ -194,7 +194,7 @@
     QEStyleDef default_style;
     XGCValues gc_val;
 
-    s->private = NULL;
+    s->priv_data = NULL;
     s->media = CSS_MEDIA_SCREEN;
 
     if (!display_str)
@@ -564,13 +564,13 @@
     }
     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);
     /* Clear structure to force crash if font is still used after
@@ -582,7 +582,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);
@@ -593,7 +593,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;
 
@@ -764,7 +764,7 @@
 
     font->ascent = xfont->ascent;
     font->descent = xfont->descent;
-    font->private = xfont;
+    font->priv_data = xfont;
     return font;
  fail:
     XFreeFontNames(list);
@@ -774,7 +774,7 @@
 
 static void term_close_font(__unused__ QEditScreen *s, QEFont *font)
 {
-    XFontStruct *xfont = font->private;
+    XFontStruct *xfont = font->priv_data;
 
     XFreeFont(display, xfont);
     /* Clear structure to force crash if font is still used after
@@ -788,7 +788,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;
 
@@ -856,7 +856,7 @@
 
     /* really no glyph : use default char in current font */
     /* Should have half-width and full-width default char patterns */
-    xfont = font->private;
+    xfont = font->priv_data;
     cs = get_char_struct(font, xfont->default_char);
     *out_font = lock_font(s, font);
     return cs;
@@ -928,13 +928,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, x_start, y, x11_str, l);
@@ -950,7 +950,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, x_start, y, x11_str, l);
--- qemacs-0.3.2dev-cvs//dev/null	2013-03-14 16:10:28.351668000 +0100
+++ qemacs-0.3.2dev-cvs/haiku.cpp	2013-03-14 20:51:17.995622912 +0100
@@ -0,0 +1,883 @@
+/*
+ * 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" {
+#include "qe.h"
+}
+
+#include <Application.h>
+#include <Bitmap.h>
+#include <FindDirectory.h>
+#include <Font.h>
+#include <InterfaceDefs.h>
+#include <Path.h>
+#include <Region.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;
+
+/* count of pending repaints */
+static vint32 repaints = 0;
+//TODO:use double-buffering with a BBitmap
+
+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();
+
+virtual void    MouseDown(BPoint where);
+virtual void    MouseUp(BPoint where);
+virtual void    MouseMoved(BPoint where, uint32 code, const BMessage *a_message);
+virtual void    KeyDown(const char *bytes, int32 numBytes);
+virtual void    KeyUp(const char *bytes, int32 numBytes);
+virtual void    Draw(BRect updateRect);
+virtual void    FrameResized(float new_width, float new_height);
+#if 0
+virtual void    WindowActivated(bool state);
+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_MOUSE_WHEEL_CHANGED:
+    	{
+    		BMessage *message = DetachCurrentMessage();
+    		bmessage_input(this, NULL, message);
+		}
+		break;
+    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(ui_color(B_DOCUMENT_BACKGROUND_COLOR));
+    //SetViewColor(0, 255, 0);
+}
+
+QEView::~QEView()
+{
+}
+
+void QEView::MouseDown(BPoint where)
+{
+    BMessage *message = Window()->DetachCurrentMessage();
+    bmessage_input(NULL, this, message);
+}
+
+void QEView::MouseUp(BPoint where)
+{
+    BMessage *message = Window()->DetachCurrentMessage();
+    bmessage_input(NULL, this, message);
+}
+
+void QEView::MouseMoved(BPoint where, uint32 code, const BMessage *a_message)
+{
+    BMessage *message = Window()->DetachCurrentMessage();
+    bmessage_input(NULL, this, message);
+}
+
+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);
+    atomic_add(&repaints, 1);
+    bmessage_input(NULL, this, message);
+}
+
+void QEView::FrameResized(float new_width, float new_height)
+{
+    BMessage *message = Window()->DetachCurrentMessage();
+    atomic_set(&repaints, 0);
+    bmessage_input(NULL, this, message);
+    BView::FrameResized(new_width, new_height);
+}
+
+
+static int haiku_probe(void)
+{
+    if (force_tty)
+        return 0;
+    return 2;
+}
+
+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;
+
+    s->bitmap_format = QEBITMAP_FORMAT_RGBA32;
+    /* BBitmap supports overlay, but not planar data */
+    //s->video_format = QEBITMAP_FORMAT_RGBA32;
+
+    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 + 1);
+
+    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)
+{
+    WindowState *ctx = (WindowState *)s->priv_data;
+    //fprintf(stderr, "%s()\n", __FUNCTION__);
+
+    ctx->v->LockLooper();
+
+    // doesn't really help
+    ctx->v->Sync();
+
+    ctx->v->UnlockLooper();
+}
+
+static int haiku_is_user_input_pending(QEditScreen *s)
+{
+    /* XXX: do it */
+    return 0;
+}
+
+/* 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_:
+        // flush queued repaints
+        if (atomic_set(&repaints, 0)) {
+            ev->expose_event.type = QE_EXPOSE_EVENT;
+            qe_handle_event(ev);
+        }
+        break;
+
+    case B_VIEW_RESIZED:
+        {
+            int32 width, height;
+            int columns, rows;
+            //event->PrintToStream();
+/*
+            if (event->FindInt32("width", &width) < B_OK)
+                break;
+            if (event->FindInt32("height", &height) < B_OK)
+                break;
+*/
+
+            ctx->v->LockLooper();
+
+            width = ctx->v->Bounds().IntegerWidth() + 1;
+            height = ctx->v->Bounds().IntegerHeight() + 1;
+
+            if (width != s->width || height != s->height)
+                ctx->v->Invalidate(ctx->v->Bounds());
+
+            s->width = width;
+            s->height = height;
+            
+            ctx->v->UnlockLooper();
+
+            //ev->expose_event.type = QE_EXPOSE_EVENT;
+            //qe_handle_event(ev);
+        }
+        break;
+
+    case B_MOUSE_MOVED:
+        {
+            BPoint pt;
+
+            ev->button_event.type = QE_MOTION_EVENT;
+            ev->button_event.x = (int)pt.x;
+            ev->button_event.y = (int)pt.y;
+            qe_handle_event(ev);
+        }
+        break;
+
+    case B_MOUSE_DOWN:
+    case B_MOUSE_UP:
+        {
+            BPoint pt;
+            uint32 buttons;
+
+            if (event->what == B_MOUSE_DOWN)
+                ev->button_event.type = QE_BUTTON_PRESS_EVENT;
+            else
+                ev->button_event.type = QE_BUTTON_RELEASE_EVENT;
+
+            if (event->FindPoint("where", &pt) < B_OK)
+                pt = BPoint(0,0);
+            ev->button_event.x = (int)pt.x;
+            ev->button_event.y = (int)pt.y;
+
+            if (event->FindInt32("buttons", (int32 *)&buttons) < B_OK)
+                buttons = (event->what == B_MOUSE_UP)?0:B_PRIMARY_MOUSE_BUTTON;
+
+
+            if (buttons & B_PRIMARY_MOUSE_BUTTON)
+                ev->button_event.button = QE_BUTTON_LEFT;
+            else if (buttons & B_SECONDARY_MOUSE_BUTTON)
+                ev->button_event.button = QE_BUTTON_MIDDLE;
+            else if (buttons & B_TERTIARY_MOUSE_BUTTON)
+                ev->button_event.button = QE_BUTTON_RIGHT;
+
+            qe_handle_event(ev);
+        }
+        break;
+
+	case B_MOUSE_WHEEL_CHANGED:
+        {
+            float delta;
+
+            ev->button_event.type = QE_BUTTON_PRESS_EVENT;
+
+            if (event->FindFloat("be:wheel_delta_y", &delta) < B_OK)
+                delta = 0.0;
+
+            if (delta > 0)
+                ev->button_event.button = QE_WHEEL_DOWN;
+            else if (delta < 0)
+                ev->button_event.button = QE_WHEEL_UP;
+            else
+            	break;
+
+            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_BS;
+                    if (meta)
+                        key = KEY_META(KEY_BS);
+                    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__);
+    drawing_mode oldMode;
+
+    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();
+
+    oldMode = ctx->v->DrawingMode();
+
+    /* XXX: suppress XOR mode */
+    if (color == QECOLOR_XOR)
+        ctx->v->SetDrawingMode(B_OP_INVERT);
+    else
+        ctx->v->SetHighColor(c);
+    ctx->v->FillRect(r);
+
+    /* XXX: suppress XOR mode */
+    if (color == QECOLOR_XOR)
+        ctx->v->SetDrawingMode(oldMode);
+    
+    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 + 1);
+    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(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)
+{
+    WindowState *ctx = (WindowState *)s->priv_data;
+    //fprintf(stderr, "%s(,%d, %d, %d, %d)\n", __FUNCTION__, x, y, w, h);
+
+    BRegion clip(BRect(x, y, x + w - 1, y + h - 1));
+
+    ctx->v->LockLooper();
+
+    ctx->v->ConstrainClippingRegion(&clip);
+
+    ctx->v->UnlockLooper();
+}
+
+static int haiku_bmp_alloc(QEditScreen *s, QEBitmap *b)
+{
+    BBitmap *bitmap;
+    color_space space = B_RGBA32;
+    uint32 flags = 0;
+
+    b->format = s->bitmap_format;
+    if (b->flags & QEBITMAP_FLAG_VIDEO) {
+    	b->format = s->video_format;
+    }
+fprintf(stderr, "%s(, [w %d, h %d])\n", __FUNCTION__, b->width, b->height);
+	switch (b->format) {
+		case QEBITMAP_FORMAT_RGB565:
+			space = B_RGB16;
+			break;
+		case QEBITMAP_FORMAT_RGB555:
+			space = B_RGB15;
+			break;
+		case QEBITMAP_FORMAT_RGB24:
+			space = B_RGB24;
+			break;
+		case QEBITMAP_FORMAT_RGBA32:
+			space = B_RGBA32;
+			break;
+		case QEBITMAP_FORMAT_YUV420P:
+			// we don't support planar overlays
+		default:
+			return -1;
+	}
+
+	BRect bounds(0, 0, b->width - 1, b->height - 1);
+	bitmap = new BBitmap(bounds, flags, space);
+	if (bitmap->InitCheck() != B_OK) {
+		delete bitmap;
+		return -1;
+	}
+    b->priv_data = bitmap;
+
+	return 0;
+}
+
+static void haiku_bmp_free(__unused__ QEditScreen *s, QEBitmap *b)
+{
+    BBitmap *bitmap = (BBitmap *)b->priv_data;
+	delete bitmap;
+}
+
+extern QEDisplay haiku_dpy = {
+    "haiku",
+    haiku_probe,
+    haiku_init,
+    haiku_close,
+    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 */
+    NULL, /* dpy_invalidate */
+    NULL, /* dpy_cursor_at */
+    haiku_bmp_alloc, /* dpy_bmp_alloc */
+    haiku_bmp_free, /* dpy_bmp_free */
+    NULL, /* dpy_bmp_draw */
+    NULL, /* dpy_bmp_lock */
+    NULL, /* dpy_bmp_unlock */
+    NULL, /* dpy_full_screen */
+    NULL, /* next */
+};
+
+static CmdOptionDef cmd_options[] = {
+    { "no-windows", "nw", NULL, CMD_OPT_BOOL, "force tty terminal usage",
+      { int_ptr: &force_tty }},
+    { NULL, NULL, NULL, 0, NULL, { NULL }}
+};
+
+static int haiku_init(void)
+{
+    QEmacsState *qs = &qe_state;
+
+    /* override default res path, to find config file at native location */
+    BPath path;
+    BString old(":");
+    old << qs->res_path;
+    qs->res_path[0] = '\0';
+    if (find_directory(B_USER_SETTINGS_DIRECTORY, &path) == B_OK) {
+        path.Append("qemacs");
+        pstrcat(qs->res_path, sizeof(qs->res_path), path.Path());
+    }
+    pstrcat(qs->res_path, sizeof(qs->res_path), old.String());
+
+    qe_register_cmd_line_options(cmd_options);
+    return qe_register_display(&haiku_dpy);
+}
+
+qe_module_init(haiku_init);
--- qemacs-0.3.2dev-cvs//dev/null	2013-03-14 16:10:28.351668000 +0100
+++ qemacs-0.3.2dev-cvs/contrib/haiku-pe2qe.sh	2013-03-14 19:17:29.552599552 +0100
@@ -0,0 +1,85 @@
+#!/bin/sh
+
+pesettings=`finddir B_USER_SETTINGS_DIRECTORY`/pe/settings
+
+fgmap=(
+"alt comment:"
+"alt error:"
+"alt keyword:"
+"alt number:"
+"alt operator:"
+"alt separator:"
+"altprocessor:"
+"attribute:"
+"char constant:html-entity"
+"comment:comment html-comment"
+"error:"
+"highlight:highlight"
+"invisibles:"
+"keyword:keyword preprocess"
+"low:window-border"
+"mark:status"
+"number:number"
+"operator:function"
+"preprocessor:"
+"selection:selection"
+"separator:"
+"string:string string-q html-string"
+"system identifier:type"
+"tag:tag"
+"tagstring:html-tag"
+"text:default mode-line minibuf"
+"user identifier:variable"
+)
+
+bgmap=(
+"low:default"
+"selection:mode-line window-border region-hilite"
+)
+
+map_pe_fg () {
+	for item in "${fgmap[@]}"; do
+		if [ "$1" = "${item%:*}" ]; then
+			echo "${item#*:}"
+			return
+		fi
+	done
+}
+
+map_pe_bg () {
+	for item in "${bgmap[@]}"; do
+		if [ "$1" = "${item%:*}" ]; then
+			echo "${item#*:}"
+			return
+		fi
+	done
+}
+
+out_style () {
+	echo "set_style(\"$1\", \"$2\", \"$3\")"
+}
+
+echo "// map Pe settings to QEmacs"
+echo "// generated by $(basename "$0") on `date`"
+
+while read line; do
+	token="${line%=*}"
+	value="${line#*=}"
+	case "$token" in
+		*color)
+			name="${token% color}"
+			qenames="$(map_pe_fg "$name")"
+			for qename in ${qenames}; do
+				#echo "color: $name -> $qename" >&2
+				out_style "$qename" "color" "$value"
+			done
+			qenames="$(map_pe_bg "$name")"
+			for qename in ${qenames}; do
+				#echo "bgcolor: $name -> $qename" >&2
+				out_style "$qename" "background-color" "$value"
+			done
+			;;
+		*)
+			;;
+	esac
+done < "$pesettings"
