diff --git a/app-editors/qemacs/patches/qemacs-0.3.3.patch b/app-editors/qemacs/patches/qemacs-0.3.3.patch index 3aa43af7e..dcd33033f 100644 --- a/app-editors/qemacs/patches/qemacs-0.3.3.patch +++ b/app-editors/qemacs/patches/qemacs-0.3.3.patch @@ -151,8 +151,8 @@ diff -urN qemacs-0.3.3.org/fbfrender.c qemacs-0.3.3/fbfrender.c 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 02:01:26.908853248 +0100 -@@ -0,0 +1,518 @@ ++++ 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. @@ -181,33 +181,156 @@ diff -urN qemacs-0.3.3.org/haiku.cpp qemacs-0.3.3/haiku.cpp + +#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; + -+typedef struct QEEventQ { -+ QEEvent ev; -+ struct QEEventQ *next; -+} QEEventQ; -+ -+QEEventQ *first_event, *last_event; +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; +} + @@ -276,18 +399,33 @@ diff -urN qemacs-0.3.3.org/haiku.cpp qemacs-0.3.3/haiku.cpp + 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"); -+printf("sw(n) = %f sz = %f\n", ctx->font.StringWidth("n"), ctx->font.Size()); -+ font_ysize = (int)(height.ascent + height.descent + 1); ++ font_ysize = (int)(height.ascent + height.descent + height.leading); + -+ xsize = 80 * font_xsize; -+ ysize = 25 * font_ysize; ++ if (w == 0) ++ w = 80; ++ if (h == 0) ++ h = 25; ++ xsize = w * font_xsize; ++ ysize = h * font_ysize; + + s->width = xsize; + s->height = ysize; @@ -300,13 +438,16 @@ diff -urN qemacs-0.3.3.org/haiku.cpp qemacs-0.3.3/haiku.cpp + + BRect frame(0, 0, s->width - 1, s->height - 1); + -+ ctx->v = new BView(frame, "qemacs", B_FOLLOW_ALL, B_WILL_DRAW); ++ QEView *v = new QEView(frame, "qemacs"); ++ ctx->v = v; + + frame.OffsetTo(200, 200); + -+ ctx->w = new BWindow(frame, "qemacs", B_TITLED_WINDOW, 0); ++ 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(); + @@ -540,11 +681,206 @@ diff -urN qemacs-0.3.3.org/haiku.cpp qemacs-0.3.3/haiku.cpp +} +#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_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__); ++ //fprintf(stderr, "%s()\n", __FUNCTION__); + + /* XXX: suppress XOR mode */ + if (color == QECOLOR_XOR) @@ -565,7 +901,7 @@ diff -urN qemacs-0.3.3.org/haiku.cpp qemacs-0.3.3/haiku.cpp +static QEFont *haiku_open_font(QEditScreen *s, int style, int size) +{ + WindowState *ctx = (WindowState *)s->priv_data; -+ fprintf(stderr, "%s()\n", __FUNCTION__); ++ //fprintf(stderr, "%s()\n", __FUNCTION__); + QEFont *font; + + font = (QEFont *)malloc(sizeof(QEFont)); @@ -578,7 +914,7 @@ diff -urN qemacs-0.3.3.org/haiku.cpp qemacs-0.3.3/haiku.cpp + font_height height; + f->GetHeight(&height); + font->ascent = (int)height.ascent; -+ font->descent = (int)height.descent; ++ font->descent = (int)(height.descent + height.leading); + font->priv_data = f; + return font; +} @@ -611,7 +947,7 @@ diff -urN qemacs-0.3.3.org/haiku.cpp qemacs-0.3.3/haiku.cpp + WindowState *ctx = (WindowState *)s->priv_data; + BFont *f = (BFont *)(font->priv_data); + int i; -+ fprintf(stderr, "%s()\n", __FUNCTION__); ++ //fprintf(stderr, "%s()\n", __FUNCTION__); + + /* XXX: suppress XOR mode */ + if (color == QECOLOR_XOR) @@ -625,16 +961,19 @@ diff -urN qemacs-0.3.3.org/haiku.cpp qemacs-0.3.3/haiku.cpp + ctx->v->SetHighColor(c); + ctx->v->SetLowColor(B_TRANSPARENT_COLOR); + ctx->v->SetFont(f); -+ ctx->v->MovePenTo(x1, y); ++ ctx->v->MovePenTo(x1, y - 1); + + char buf[10]; + unsigned int cc; + ++ BString text; + for(i=0;iv->DrawString(buf); ++ text << buf; ++ //ctx->v->DrawString(buf); + } ++ ctx->v->DrawString(text.String()); + + ctx->v->UnlockLooper(); + @@ -665,8 +1004,15 @@ diff -urN qemacs-0.3.3.org/haiku.cpp qemacs-0.3.3/haiku.cpp + 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); +} +