From 4111eca16f81a84a174cbb1a933c44f63dc1e9a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Revol?= Date: Tue, 12 Mar 2013 14:48:02 +0000 Subject: [PATCH] Patch for QEmacs (CVS version) The CVS version has diverged from the official version... --- .../qemacs/patches/qemacs-0.3.2dev-cvs.patch | 1445 +++++++++++++++++ 1 file changed, 1445 insertions(+) create mode 100644 app-editors/qemacs/patches/qemacs-0.3.2dev-cvs.patch diff --git a/app-editors/qemacs/patches/qemacs-0.3.2dev-cvs.patch b/app-editors/qemacs/patches/qemacs-0.3.2dev-cvs.patch new file mode 100644 index 000000000..07ef820e3 --- /dev/null +++ b/app-editors/qemacs/patches/qemacs-0.3.2dev-cvs.patch @@ -0,0 +1,1445 @@ +Index: Makefile +=================================================================== +RCS file: /sources/qemacs/qemacs/Makefile,v +retrieving revision 1.50 +diff -u -r1.50 Makefile +--- Makefile 5 Jun 2008 07:14:12 -0000 1.50 ++++ Makefile 12 Mar 2013 14:45:26 -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 +@@ -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 +--- cfb.c 8 Apr 2008 06:55:44 -0000 1.8 ++++ cfb.c 12 Mar 2013 14:45:26 -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 +--- configure 17 Apr 2008 15:06:44 -0000 1.15 ++++ configure 12 Mar 2013 14:45:26 -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 +--- display.h 11 Jan 2008 11:29:28 -0000 1.11 ++++ display.h 12 Mar 2013 14:45:26 -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; +@@ -153,7 +153,7 @@ + /* 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 +--- fbfrender.c 8 Jan 2008 16:37:54 -0000 1.10 ++++ fbfrender.c 12 Mar 2013 14:45:26 -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 +--- html2png.c 11 Jan 2008 11:29:28 -0000 1.12 ++++ html2png.c 12 Mar 2013 14:45:26 -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 +--- qe.h 4 May 2008 15:54:39 -0000 1.96 ++++ qe.h 12 Mar 2013 14:45:28 -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 +--- tty.c 23 Apr 2008 15:30:33 -0000 1.50 ++++ tty.c 12 Mar 2013 14:45:28 -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 +--- win32.c 23 Apr 2008 15:29:35 -0000 1.15 ++++ win32.c 12 Mar 2013 14:45:29 -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 +--- x11.c 15 Apr 2008 23:24:04 -0000 1.28 ++++ x11.c 12 Mar 2013 14:45:29 -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); +--- /dev/null 2013-03-12 16:43:58.197398000 +0100 ++++ haiku.cpp 2013-03-12 06:53:41.158859264 +0100 +@@ -0,0 +1,874 @@ ++/* ++ * 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 ++#include ++#include ++#include ++#include ++#include ++#include ++ ++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(ui_color(B_DOCUMENT_BACKGROUND_COLOR)); ++} ++ ++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 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; ++ ++ 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", ×tamp_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__); ++ ++ /* 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;iwidth = 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;iv->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(); ++} ++ ++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 */ ++}; ++ ++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) ++{ ++ qe_register_cmd_line_options(cmd_options); ++ return qe_register_display(&haiku_dpy); ++} ++ ++qe_module_init(haiku_init);