diff --git a/app-editors/vim/patches/vim-7.2.patch b/app-editors/vim/patches/vim-7.2.patch new file mode 100644 index 000000000..efeaa27e8 --- /dev/null +++ b/app-editors/vim/patches/vim-7.2.patch @@ -0,0 +1,5327 @@ +diff -Naur vim72/Makefile vim72.haiku/Makefile +--- vim72/Makefile 2009-04-19 20:53:31.000000000 +0000 ++++ vim72.haiku/Makefile 2009-04-18 09:14:47.000000000 +0000 +@@ -185,6 +185,14 @@ + # - Rename the executables to vimos2.exe, xxdos2.exe and teeos2.exe and copy + # them to here. + # - "make os2bin". ++# ++# BeOS/Haiku OS ++# - unpack Unix sources ++# - aplly Haiku patch ++# - go to "src" directory ++# - regenerate configure by "autoconf -o auto/configure configure.in" command ++# - use typical Unix configure and build procedures ++# - to install under Haiku use "make install_beos" command. + + VIMVER = vim-$(MAJOR).$(MINOR) + VERSION = $(MAJOR)$(MINOR) +diff -Naur vim72/src/Makefile vim72.haiku/src/Makefile +--- vim72/src/Makefile 2009-04-19 20:53:35.000000000 +0000 ++++ vim72.haiku/src/Makefile 2009-04-23 22:26:29.000000000 +0000 +@@ -1208,6 +1208,19 @@ + # too: + #EXTRA_LIBS = /usr/openwin/lib/libXmu.sa -lm + ++### BeOS GUI ++BEOSGUI_SRC = gui.c gui_beos.cc pty.c ++BEOSGUI_OBJ = objects/gui.o objects/gui_beos.o objects/pty.o ++BEOSGUI_DEFS = -DFEAT_GUI_BEOS ++BEOSGUI_IPATH = ++BEOSGUI_LIBS_DIR = ++BEOSGUI_LIBS1 = -lbe -lroot -ltracker ++BEOSGUI_LIBS2 = ++BEOSGUI_INSTALL = install_normal ++BEOSGUI_TARGETS = installglinks ++BEOSGUI_MAN_TARGETS = installghelplinks ++BEOSGUI_TESTTARGET = gui ++ + # PHOTON GUI + PHOTONGUI_SRC = gui.c gui_photon.c pty.c + PHOTONGUI_OBJ = objects/gui.o objects/gui_photon.o objects/pty.o +@@ -2381,6 +2394,9 @@ + objects/gui_athena.o: gui_athena.c + $(CCC) -o $@ gui_athena.c + ++objects/gui_beos.o: gui_beos.cc ++ $(CCC) -o $@ gui_beos.cc ++ + objects/gui_beval.o: gui_beval.c + $(CCC) -o $@ gui_beval.c + +@@ -2486,6 +2502,9 @@ + objects/os_beos.o: os_beos.c + $(CCC) -o $@ os_beos.c + ++objects/os_beos.rsrc: os_beos.rdef ++ rc -o $@ os_beos.rdef ++ + objects/os_qnx.o: os_qnx.c + $(CCC) -o $@ os_qnx.c + +@@ -2645,6 +2664,17 @@ + + + ############################################################################### ++### BeOS/Haiku OS installation ++### ++### This rule add resources to already installed vim binary ++### copy some required files and update system MIME database ++ ++install_beos: install objects/os_beos.rsrc ++ xres -o $(DEST_BIN)/$(VIMTARGET) objects/os_beos.rsrc ++ $(INSTALL_DATA) $(SCRIPTSOURCE)/rgb.txt $(DEST_RT) ++ mimeset $(DEST_BIN)/$(VIMTARGET) ++ ++############################################################################### + ### (automatically generated by 'make depend') + ### Dependencies: + objects/buffer.o: buffer.c vim.h auto/config.h feature.h os_unix.h auto/osdef.h \ +diff -Naur vim72/src/configure.in vim72.haiku/src/configure.in +--- vim72/src/configure.in 2009-04-19 20:53:35.000000000 +0000 ++++ vim72.haiku/src/configure.in 2009-04-18 09:16:24.000000000 +0000 +@@ -69,11 +69,13 @@ + + OS_EXTRA_SRC=""; OS_EXTRA_OBJ="" + +-dnl Check for BeOS, which needs an extra source file +-AC_MSG_CHECKING(for BeOS) ++dnl Check for BeOS/Haiku, which needs an extra source file ++AC_MSG_CHECKING(for BeOS/Haiku) + case `uname` in + BeOS) OS_EXTRA_SRC=os_beos.c; OS_EXTRA_OBJ=objects/os_beos.o + BEOS=yes; AC_MSG_RESULT(yes);; ++ Haiku) OS_EXTRA_SRC=os_beos.c; OS_EXTRA_OBJ=objects/os_beos.o ++ BEOS=yes; AC_MSG_RESULT(yes);; + *) BEOS=no; AC_MSG_RESULT(no);; + esac + +@@ -1196,11 +1198,11 @@ + fi + fi + +-test "x$with_x" = xno -a "x$MACOSX" != "xyes" -a "x$QNX" != "xyes" && enable_gui=no ++test "x$with_x" = xno -a "x$BEOS" != "xyes" -a "x$MACOSX" != "xyes" -a "x$QNX" != "xyes" && enable_gui=no + + AC_MSG_CHECKING(--enable-gui argument) + AC_ARG_ENABLE(gui, +- [ --enable-gui[=OPTS] X11 GUI [default=auto] [OPTS=auto/no/gtk/gtk2/gnome/gnome2/motif/athena/neXtaw/photon/carbon]], , enable_gui="auto") ++ [ --enable-gui[=OPTS] X11 GUI [default=auto] [OPTS=auto/no/gtk/gtk2/gnome/gnome2/motif/athena/neXtaw/beos/photon/carbon]], , enable_gui="auto") + + dnl Canonicalize the --enable-gui= argument so that it can be easily compared. + dnl Do not use character classes for portability with old tools. +@@ -1215,10 +1217,24 @@ + SKIP_ATHENA=YES + SKIP_NEXTAW=YES + SKIP_PHOTON=YES ++SKIP_BEOS=YES + SKIP_CARBON=YES + GUITYPE=NONE + +-if test "x$QNX" = "xyes" -a "x$with_x" = "xno" ; then ++ ++if test "x$BEOS" = "xyes"; then ++ SKIP_BEOS= ++ case "$enable_gui_canon" in ++ no) AC_MSG_RESULT(no GUI support) ++ SKIP_BEOS=YES ;; ++ yes|"") AC_MSG_RESULT(yes - automatic GUI support) ;; ++ auto) AC_MSG_RESULT(auto - automatic GUI support) ;; ++ beos) AC_MSG_RESULT(BeOS GUI support) ;; ++ *) AC_MSG_RESULT([Sorry, $enable_gui GUI is not supported]) ++ SKIP_BEOS=YES ;; ++ esac ++ ++elif test "x$QNX" = "xyes" -a "x$with_x" = "xno" ; then + SKIP_PHOTON= + case "$enable_gui_canon" in + no) AC_MSG_RESULT(no GUI support) +@@ -1383,6 +1399,7 @@ + SKIP_ATHENA=YES; + SKIP_NEXTAW=YES; + SKIP_PHOTON=YES; ++ SKIP_BEOS=YES + SKIP_CARBON=YES + fi + +@@ -1997,6 +2014,11 @@ + enable_fontset="no" + fi + ++dnl There is no test for the BeOS GUI, if it's selected it's used ++if test -z "$SKIP_BEOS"; then ++ GUITYPE=BEOSGUI ++fi ++ + if test -z "$SKIP_PHOTON"; then + GUITYPE=PHOTONGUI + fi +diff -Naur vim72/src/eval.c vim72.haiku/src/eval.c +--- vim72/src/eval.c 2009-04-19 20:53:31.000000000 +0000 ++++ vim72.haiku/src/eval.c 2009-04-18 09:16:25.000000000 +0000 +@@ -11333,6 +11333,9 @@ + #ifdef __BEOS__ + "beos", + #endif ++#ifdef __HAIKU__ ++ "haiku", ++#endif + #ifdef MSDOS + # ifdef DJGPP + "dos32", +@@ -11501,6 +11504,9 @@ + #ifdef FEAT_GUI_GNOME + "gui_gnome", + #endif ++#ifdef FEAT_GUI_BEOS ++ "gui_beos", ++#endif + #ifdef FEAT_GUI_MAC + "gui_mac", + #endif +diff -Naur vim72/src/ex_docmd.c vim72.haiku/src/ex_docmd.c +--- vim72/src/ex_docmd.c 2009-04-19 20:53:32.000000000 +0000 ++++ vim72.haiku/src/ex_docmd.c 2009-04-25 20:58:56.000000000 +0000 +@@ -6693,6 +6693,7 @@ + || (defined(FEAT_GUI_GTK) && defined(FEAT_DND)) \ + || defined(FEAT_GUI_MSWIN) \ + || defined(FEAT_GUI_MAC) \ ++ || defined(FEAT_GUI_BEOS) \ + || defined(PROTO) + + /* +diff -Naur vim72/src/feature.h vim72.haiku/src/feature.h +--- vim72/src/feature.h 2009-04-19 20:53:32.000000000 +0000 ++++ vim72.haiku/src/feature.h 2009-05-03 13:31:26.000000000 +0000 +@@ -643,6 +643,14 @@ + /* #define FEAT_MBYTE_IME */ + # endif + ++/* ++ * +multi_byte_ime BeOS/Haiku input method support. ++ * Requires +multi_byte. ++ */ ++#if defined(FEAT_BIG) && defined(FEAT_GUI_BEOS) && !defined(FEAT_MBYTE_IME) ++ #define FEAT_MBYTE_IME ++# endif ++ + #if defined(FEAT_MBYTE_IME) && !defined(FEAT_MBYTE) + # define FEAT_MBYTE + #endif +@@ -768,7 +776,7 @@ + /* + * +browse ":browse" command. + */ +-#if defined(FEAT_NORMAL) && (defined(FEAT_GUI_MSWIN) || defined(FEAT_GUI_MOTIF) || defined(FEAT_GUI_ATHENA) || defined(FEAT_GUI_GTK) || defined(FEAT_GUI_PHOTON) || defined(FEAT_GUI_MAC)) ++#if defined(FEAT_NORMAL) && (defined(FEAT_GUI_MSWIN) || defined(FEAT_GUI_MOTIF) || defined(FEAT_GUI_ATHENA) || defined(FEAT_GUI_BEOS) || defined(FEAT_GUI_GTK) || defined(FEAT_GUI_PHOTON) || defined(FEAT_GUI_MAC)) + # define FEAT_BROWSE + #endif + +@@ -782,6 +790,7 @@ + && defined(HAVE_X11_XPM_H)) \ + || defined(FEAT_GUI_GTK) \ + || defined(FEAT_GUI_PHOTON) \ ++ || defined(FEAT_GUI_BEOS) \ + || defined(FEAT_GUI_MSWIN) \ + || defined(FEAT_GUI_MAC) + # define FEAT_CON_DIALOG +@@ -798,7 +807,8 @@ + #if defined(FEAT_GUI_DIALOG) && \ + (defined(FEAT_GUI_MOTIF) || defined(FEAT_GUI_ATHENA) \ + || defined(FEAT_GUI_GTK) || defined(FEAT_GUI_MSWIN) \ +- || defined(FEAT_GUI_PHOTON) || defined(FEAT_GUI_MAC)) ++ || defined(FEAT_GUI_PHOTON) || defined(FEAT_GUI_MAC))\ ++ || defined(FEAT_GUI_BEOS) + # define FEAT_GUI_TEXTDIALOG + #endif + +diff -Naur vim72/src/gui.c vim72.haiku/src/gui.c +--- vim72/src/gui.c 2009-04-19 20:53:32.000000000 +0000 ++++ vim72.haiku/src/gui.c 2009-04-18 09:16:26.000000000 +0000 +@@ -58,7 +58,7 @@ + gui_start() + { + char_u *old_term; +-#if defined(UNIX) && !defined(__BEOS__) && !defined(MACOS_X) ++#if defined(UNIX) && !defined(__HAIKU__) && !defined(__BEOS__) && !defined(MACOS_X) + # define MAY_FORK + int dofork = TRUE; + #endif +@@ -626,7 +626,7 @@ + gui_exit(rc) + int rc; + { +-#ifndef __BEOS__ ++#if !defined(__BEOS__) && !defined(__HAIKU__) + /* don't free the fonts, it leads to a BUS error + * richard@whitequeen.com Jul 99 */ + free_highlight_fonts(); +@@ -1297,7 +1297,11 @@ + again: + busy = TRUE; + +- /* Flush pending output before redrawing */ ++#ifdef FEAT_GUI_BEOS ++ vim_lock_screen(); ++#endif ++ ++ /* Flush pending output before redrawing */ + out_flush(); + + gui.num_cols = (pixel_width - gui_get_base_width()) / gui.char_width; +@@ -1319,7 +1323,11 @@ + || gui.num_rows != Rows || gui.num_cols != Columns) + shell_resized(); + +- gui_update_scrollbars(TRUE); ++#ifdef FEAT_GUI_BEOS ++ vim_unlock_screen(); ++#endif ++ ++ gui_update_scrollbars(TRUE); + gui_update_cursor(FALSE, TRUE); + #if defined(FEAT_XIM) && !defined(HAVE_GTK2) + xim_set_status_area(); +diff -Naur vim72/src/gui.h vim72.haiku/src/gui.h +--- vim72/src/gui.h 2009-04-19 20:53:32.000000000 +0000 ++++ vim72.haiku/src/gui.h 2009-04-18 09:16:26.000000000 +0000 +@@ -33,6 +33,10 @@ + # include + #endif + ++#ifdef FEAT_GUI_BEOS ++# include "gui_beos.h" ++#endif ++ + #ifdef FEAT_GUI_MAC + # include + /*# include */ +@@ -83,7 +87,7 @@ + * GUIs that support dropping files on a running Vim. + */ + #if defined(FEAT_GUI_MSWIN) || defined(FEAT_GUI_MAC) \ +- || defined(FEAT_GUI_GTK) ++ || defined(FEAT_GUI_BEOS) || defined(FEAT_GUI_GTK) + # define HAVE_DROP_FILE + #endif + +@@ -216,6 +220,9 @@ + scroll_shift is set to the number of shifts + to reduce the count. */ + #endif ++#if FEAT_GUI_BEOS ++ VimScrollBar *id; /* Pointer to real scroll bar */ ++#endif + #ifdef FEAT_GUI_MAC + ControlHandle id; /* A handle to the scrollbar */ + #endif +@@ -456,6 +463,14 @@ + guicolor_T currSpColor; /* Current special text color */ + #endif + ++#ifdef FEAT_GUI_BEOS ++ VimApp *vimApp; ++ VimWindow *vimWindow; ++ VimFormView *vimForm; ++ VimTextAreaView *vimTextArea; ++ int vdcmp; /* Vim Direct Communication Message Port */ ++#endif ++ + #ifdef FEAT_GUI_MAC + WindowPtr VimWindow; + MenuHandle MacOSHelpMenu; /* Help menu provided by the MacOS */ +diff -Naur vim72/src/gui_beos.cc vim72.haiku/src/gui_beos.cc +--- vim72/src/gui_beos.cc 1970-01-01 00:00:00.000000000 +0000 ++++ vim72.haiku/src/gui_beos.cc 2009-05-04 21:17:48.000000000 +0000 +@@ -0,0 +1,4186 @@ ++/* vi:set ts=8 sts=4 sw=4: ++ * ++ * VIM - Vi IMproved by Bram Moolenaar ++ * BeBox GUI support Copyright 1998 by Olaf Seibert. ++ * All Rights Reserved. ++ * ++ * Do ":help uganda" in Vim to read copying and usage conditions. ++ * Do ":help credits" in Vim to see a list of people who contributed. ++ * ++ * BeOS GUI. ++ * ++ * GUI support for the Buzzword Enhanced Operating System. ++ * ++ * Ported to R4 by Richard Offer Jul 99 ++ * ++ * Haiku support by Siarzhuk Zharski gmx.li> Apr-Mai 2009 ++ * ++ */ ++ ++/* ++ * Structure of the BeOS GUI code: ++ * ++ * There are 3 threads. ++ * 1. The initial thread. In gui_mch_prepare() this gets to run the ++ * BApplication message loop. But before it starts doing that, ++ * it creates thread 2 ++ * 2. The main() thread. This thread is created in gui_mch_prepare() ++ * and its purpose in life is to call main(argc, argv) again. ++ * This thread is doing the bulk of the work. ++ * 3. Sooner or later, a window is opened by the main() thread. This ++ * causes a second message loop to be created: the window thread. ++ * ++ * == alternatively === ++ * ++ * #if RUN_BAPPLICATION_IN_NEW_THREAD... ++ * ++ * 1. The initial thread. In gui_mch_prepare() this gets to spawn ++ * thread 2. After doing that, it returns to main() to do the ++ * bulk of the work, being the main() thread. ++ * 2. Runs the BApplication. ++ * 3. The window thread, just like in the first case. ++ * ++ * This second alternative is cleaner from Vim's viewpoint. However, ++ * the BeBook seems to assume everywhere that the BApplication *must* ++ * run in the initial thread. So perhaps doing otherwise is very wrong. ++ * ++ * However, from a B_SINGLE_LAUNCH viewpoint, the first is better. ++ * If Vim is marked "Single Launch" in its application resources, ++ * and a file is dropped on the Vim icon, and another Vim is already ++ * running, the file is passed on to the earlier Vim. This happens ++ * in BApplication::Run(). So we want Vim to terminate if ++ * BApplication::Run() terminates. (See the BeBook, on BApplication. ++ * However, it seems that the second copy of Vim isn't even started ++ * in this case... which is for the better since I wouldn't know how ++ * to detect this case.) ++ * ++ * Communication between these threads occurs mostly by translating ++ * BMessages that come in and posting an appropriate translation on ++ * the VDCMP (Vim Direct Communication Message Port). Therefore the ++ * actions required for keypresses and window resizes, etc, are mostly ++ * performed in the main() thread. ++ * ++ * A notable exception to this is the Draw() event. The redrawing of ++ * the window contents is performed asynchronously from the window ++ * thread. To make this work correctly, a locking protocol is used when ++ * any thread is accessing the essential variables that are used by ++ * the window thread. ++ * ++ * This locking protocol consists of locking Vim's window. This is both ++ * convenient and necessary. ++ */ ++extern "C" { ++ ++#include ++#include ++#include "vim.h" ++#include "globals.h" ++#include "proto.h" ++#include "version.h" ++ ++} /* extern "C" */ ++ ++/* ---------------- start of header part ---------------- */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#ifdef __HAIKU__ ++//#include ++#endif ++ ++class VimApp; ++class VimFormView; ++class VimTextAreaView; ++class VimWindow; ++ ++extern key_map *keyMap; ++extern char *keyMapChars; ++ ++extern int main(int argc, char **argv); ++ ++#ifndef B_MAX_PORT_COUNT ++#define B_MAX_PORT_COUNT 255 ++#endif ++ ++/* ++ * VimApp seems comparable to the X "vimShell" ++ */ ++class VimApp: public BApplication ++{ ++ typedef BApplication Inherited; ++ public: ++ VimApp(const char *appsig); ++ ~VimApp(); ++ ++ // callbacks: ++#if 0 ++ virtual void DispatchMessage(BMessage *m, BHandler *h) ++ { ++ m->PrintToStream(); ++ Inherited::DispatchMessage(m, h); ++ } ++#endif ++ virtual void ReadyToRun(); ++ virtual void ArgvReceived(int32 argc, char **argv); ++ virtual void RefsReceived(BMessage *m); ++ virtual bool QuitRequested(); ++ virtual void MessageReceived(BMessage *m); ++ ++ static void SendRefs(BMessage *m, bool changedir); ++ ++ sem_id fFilePanelSem; ++ BFilePanel fSavePanel; ++ BFilePanel fOpenPanel; ++ BPath fBrowsedPath; ++ private: ++}; ++ ++class VimWindow: public BWindow ++{ ++ typedef BWindow Inherited; ++ public: ++ VimWindow(); ++ ~VimWindow(); ++ ++ // virtual void DispatchMessage(BMessage *m, BHandler *h); ++ virtual void WindowActivated(bool active); ++ virtual bool QuitRequested(); ++ ++ VimFormView *formView; ++ ++ private: ++ void init(); ++ ++}; ++ ++class VimFormView: public BView ++{ ++ typedef BView Inherited; ++ public: ++ VimFormView(BRect frame); ++ ~VimFormView(); ++ ++ // callbacks: ++ virtual void AllAttached(); ++ virtual void FrameResized(float new_width, float new_height); ++ ++#define MENUBAR_MARGIN 1 ++ float MenuHeight() const ++ { return menuBar ? menuBar->Frame().Height() + MENUBAR_MARGIN: 0; } ++ BMenuBar *MenuBar() const ++ { return menuBar; } ++ ++ private: ++ void init(BRect); ++ ++ BMenuBar *menuBar; ++ VimTextAreaView *textArea; ++}; ++ ++class VimTextAreaView: public BView ++{ ++ typedef BView Inherited; ++ public: ++ VimTextAreaView(BRect frame); ++ ~VimTextAreaView(); ++ ++ // callbacks: ++ virtual void Draw(BRect updateRect); ++ virtual void KeyDown(const char *bytes, int32 numBytes); ++ virtual void MouseDown(BPoint point); ++ virtual void MouseUp(BPoint point); ++ virtual void MouseMoved(BPoint point, uint32 transit, const BMessage *message); ++ virtual void MessageReceived(BMessage *m); ++ ++ // own functions: ++ int mchInitFont(char_u *name); ++ void mchDrawString(int row, int col, char_u *s, int len, int flags); ++ void mchClearBlock(int row1, int col1, int row2, int col2); ++ void mchClearAll(); ++ void mchDeleteLines(int row, int num_lines); ++ void mchInsertLines(int row, int num_lines); ++ ++ static void guiSendMouseEvent(int button, int x, int y, int repeated_click, int_u modifiers); ++ static void guiMouseMoved(int x, int y); ++ static void guiBlankMouse(bool should_hide); ++ static int_u mouseModifiersToVim(int32 beModifiers); ++ ++ int32 mouseDragEventCount; ++ ++#ifdef FEAT_MBYTE_IME ++ void DrawIMString(void); ++#endif ++ ++ private: ++ void init(BRect); ++ ++ int_u vimMouseButton; ++ int_u vimMouseModifiers; ++ ++#ifdef FEAT_MBYTE_IME ++ struct { ++ BMessenger* messenger; ++ BMessage* message; ++ BPoint location; ++ int row; ++ int col; ++ int count; ++ } IMData; ++#endif ++}; ++ ++class VimScrollBar: public BScrollBar ++{ ++ typedef BScrollBar Inherited; ++ public: ++ VimScrollBar(scrollbar_T *gsb, orientation posture); ++ ~VimScrollBar(); ++ ++ virtual void ValueChanged(float newValue); ++ virtual void MouseUp(BPoint where); ++ void SetValue(float newval); ++ scrollbar_T *getGsb() ++ { return gsb; } ++ ++ int32 scrollEventCount; ++ ++ private: ++ scrollbar_T *gsb; ++ float ignoreValue; ++}; ++ ++ ++/* ++ * For caching the fonts that are used; ++ * Vim seems rather sloppy in this regard. ++ */ ++class VimFont: public BFont ++{ ++ typedef BFont Inherited; ++ public: ++ VimFont(); ++ VimFont(const VimFont *rhs); ++ VimFont(const BFont *rhs); ++ VimFont(const VimFont &rhs); ++ ~VimFont(); ++ ++ VimFont *next; ++ int refcount; ++ char_u *name; ++ ++ private: ++ void init(); ++}; ++ ++#if defined(FEAT_GUI_DIALOG) ++ ++class VimDialog : public BWindow ++{ ++ typedef BWindow Inherited; ++ ++ BButton* _CreateButton(int32 which, const char* label); ++ ++ public: ++ VimDialog(int type, const char *title, const char *message, ++ const char *buttons, int dfltbutton, const char *textfield); ++ ~VimDialog(); ++ ++ int Go(); ++ ++ virtual void MessageReceived(BMessage *msg); ++ ++ private: ++ sem_id fDialogSem; ++ int fDialogValue; ++ BList fButtonsList; ++ BTextView* fMessageView; ++ BTextControl* fInputControl; ++ const char* fInputValue; ++}; ++ ++class VimDialogView : public BView ++{ ++ typedef BView Inherited; ++ public: ++ VimDialogView(BRect frame); ++ ~VimDialogView(); ++ ++ virtual void Draw(BRect updateRect); ++ ++ void InitIcon(int32 type); ++ ++ BBitmap* fIconBitmap; ++}; ++ ++#endif /* FEAT_GUI_DIALOG */ ++ ++/* ---------------- end of GUI classes ---------------- */ ++ ++struct MainArgs { ++ int argc; ++ char **argv; ++}; ++ ++/* ++ * These messages are copied through the VDCMP. ++ * Therefore they ought not to have anything fancy. ++ * They must be of POD type (Plain Old Data) ++ * as the C++ standard calls them. ++ */ ++ ++#define KEY_MSG_BUFSIZ 7 ++#if KEY_MSG_BUFSIZ < MAX_KEY_CODE_LEN ++#error Increase KEY_MSG_BUFSIZ! ++#endif ++ ++struct VimKeyMsg { ++ char_u length; ++ char_u chars[KEY_MSG_BUFSIZ]; /* contains Vim encoding */ ++#ifdef FEAT_MBYTE ++ bool csi_escape; ++#endif ++}; ++ ++struct VimResizeMsg { ++ int width; ++ int height; ++}; ++ ++struct VimScrollBarMsg { ++ VimScrollBar *sb; ++ long value; ++ int stillDragging; ++}; ++ ++struct VimMenuMsg { ++ vimmenu_T *guiMenu; ++}; ++ ++struct VimMouseMsg { ++ int button; ++ int x; ++ int y; ++ int repeated_click; ++ int_u modifiers; ++}; ++ ++struct VimMouseMovedMsg { ++ int x; ++ int y; ++}; ++ ++struct VimFocusMsg { ++ bool active; ++}; ++ ++struct VimRefsMsg { ++ BMessage *message; ++ bool changedir; ++}; ++ ++struct VimMsg { ++ enum VimMsgType { ++ Key, Resize, ScrollBar, Menu, Mouse, MouseMoved, Focus, Refs ++ }; ++ ++ union { ++ struct VimKeyMsg Key; ++ struct VimResizeMsg NewSize; ++ struct VimScrollBarMsg Scroll; ++ struct VimMenuMsg Menu; ++ struct VimMouseMsg Mouse; ++ struct VimMouseMovedMsg MouseMoved; ++ struct VimFocusMsg Focus; ++ struct VimRefsMsg Refs; ++ } u; ++}; ++ ++#define RGB(r, g, b) ((char_u)(r) << 16 | (char_u)(g) << 8 | (char_u)(b) << 0) ++#define GUI_TO_RGB(g) { (g) >> 16, (g) >> 8, (g) >> 0, 255 } ++ ++/* ---------------- end of header part ---------------- */ ++ ++static struct specialkey ++{ ++ uint16 BeKeys; ++#define KEY(a,b) ((a)<<8|(b)) ++#define K(a) KEY(0,a) // for ASCII codes ++#define F(b) KEY(1,b) // for scancodes ++ char_u vim_code0; ++ char_u vim_code1; ++} special_keys[] = ++{ ++ {K(B_UP_ARROW), 'k', 'u'}, ++ {K(B_DOWN_ARROW), 'k', 'd'}, ++ {K(B_LEFT_ARROW), 'k', 'l'}, ++ {K(B_RIGHT_ARROW), 'k', 'r'}, ++ {K(B_BACKSPACE), 'k', 'b'}, ++ {K(B_INSERT), 'k', 'I'}, ++ {K(B_DELETE), 'k', 'D'}, ++ {K(B_HOME), 'k', 'h'}, ++ {K(B_END), '@', '7'}, ++ {K(B_PAGE_UP), 'k', 'P'}, /* XK_Prior */ ++ {K(B_PAGE_DOWN), 'k', 'N'}, /* XK_Next, */ ++ ++#define FIRST_FUNCTION_KEY 11 ++ {F(B_F1_KEY), 'k', '1'}, ++ {F(B_F2_KEY), 'k', '2'}, ++ {F(B_F3_KEY), 'k', '3'}, ++ {F(B_F4_KEY), 'k', '4'}, ++ {F(B_F5_KEY), 'k', '5'}, ++ {F(B_F6_KEY), 'k', '6'}, ++ {F(B_F7_KEY), 'k', '7'}, ++ {F(B_F8_KEY), 'k', '8'}, ++ {F(B_F9_KEY), 'k', '9'}, ++ {F(B_F10_KEY), 'k', ';'}, ++ ++ {F(B_F11_KEY), 'F', '1'}, ++ {F(B_F12_KEY), 'F', '2'}, ++ // {XK_F13, 'F', '3'}, /* would be print screen/ */ ++ /* sysreq */ ++ {F(0x0F), 'F', '4'}, /* scroll lock */ ++ {F(0x10), 'F', '5'}, /* pause/break */ ++ // {XK_F16, 'F', '6'}, ++ // {XK_F17, 'F', '7'}, ++ // {XK_F18, 'F', '8'}, ++ // {XK_F19, 'F', '9'}, ++ // {XK_F20, 'F', 'A'}, ++ // ++ // {XK_F21, 'F', 'B'}, ++ // {XK_F22, 'F', 'C'}, ++ // {XK_F23, 'F', 'D'}, ++ // {XK_F24, 'F', 'E'}, ++ // {XK_F25, 'F', 'F'}, ++ // {XK_F26, 'F', 'G'}, ++ // {XK_F27, 'F', 'H'}, ++ // {XK_F28, 'F', 'I'}, ++ // {XK_F29, 'F', 'J'}, ++ // {XK_F30, 'F', 'K'}, ++ // ++ // {XK_F31, 'F', 'L'}, ++ // {XK_F32, 'F', 'M'}, ++ // {XK_F33, 'F', 'N'}, ++ // {XK_F34, 'F', 'O'}, ++ // {XK_F35, 'F', 'P'}, /* keysymdef.h defines up to F35 */ ++ ++ // {XK_Help, '%', '1'}, /* XK_Help */ ++ {F(B_PRINT_KEY), '%', '9'}, ++ ++#if 0 ++ /* Keypad keys: */ ++ {F(0x48), 'k', 'l'}, /* XK_KP_Left */ ++ {F(0x4A), 'k', 'r'}, /* XK_KP_Right */ ++ {F(0x38), 'k', 'u'}, /* XK_KP_Up */ ++ {F(0x59), 'k', 'd'}, /* XK_KP_Down */ ++ {F(0x64), 'k', 'I'}, /* XK_KP_Insert */ ++ {F(0x65), 'k', 'D'}, /* XK_KP_Delete */ ++ {F(0x37), 'k', 'h'}, /* XK_KP_Home */ ++ {F(0x58), '@', '7'}, /* XK_KP_End */ ++ {F(0x39), 'k', 'P'}, /* XK_KP_Prior */ ++ {F(0x60), 'k', 'N'}, /* XK_KP_Next */ ++ {F(0x49), '&', '8'}, /* XK_Undo, keypad 5 */ ++#endif ++ ++ /* End of list marker: */ ++ {0, 0, 0} ++}; ++ ++#define NUM_SPECIAL_KEYS (sizeof(special_keys)/sizeof(special_keys[0])) ++ ++/* ---------------- VimApp ---------------- */ ++ ++ static void ++docd(BPath &path) ++{ ++ mch_chdir(path.Path()); ++ /* Do this to get the side effects of a :cd command */ ++ do_cmdline_cmd((char_u *)"cd ."); ++} ++ ++/* ++ * Really handle dropped files and folders. ++ */ ++ static void ++RefsReceived(BMessage *m, bool changedir) ++{ ++ uint32 type; ++ int32 count; ++ ++ //m->PrintToStream(); ++ switch (m->what) { ++ case B_REFS_RECEIVED: ++ case B_SIMPLE_DATA: ++ m->GetInfo("refs", &type, &count); ++ if (type != B_REF_TYPE) ++ goto bad; ++ break; ++ case B_ARGV_RECEIVED: ++ m->GetInfo("argv", &type, &count); ++ if (type != B_STRING_TYPE) ++ goto bad; ++ if (changedir) { ++ char *dirname; ++ if (m->FindString("cwd", (const char **) &dirname) == B_OK) { ++ chdir(dirname); ++ do_cmdline_cmd((char_u *)"cd ."); ++ } ++ } ++ break; ++ default: ++bad: ++ //fprintf(stderr, "bad!\n"); ++ delete m; ++ return; ++ } ++ ++#ifdef FEAT_VISUAL ++ reset_VIsual(); ++#endif ++ ++ char_u **fnames; ++ fnames = (char_u **) alloc(count * sizeof(char_u *)); ++ int fname_index = 0; ++ ++ switch (m->what) { ++ case B_REFS_RECEIVED: ++ case B_SIMPLE_DATA: ++ //fprintf(stderr, "case B_REFS_RECEIVED\n"); ++ for (int i = 0; i < count; ++i) ++ { ++ entry_ref ref; ++ if (m->FindRef("refs", i, &ref) == B_OK) { ++ BEntry entry(&ref, false); ++ BPath path; ++ entry.GetPath(&path); ++ ++ /* Change to parent directory? */ ++ if (changedir) { ++ BPath parentpath; ++ path.GetParent(&parentpath); ++ docd(parentpath); ++ } ++ ++ /* Is it a directory? If so, cd into it. */ ++ BDirectory bdir(&ref); ++ if (bdir.InitCheck() == B_OK) { ++ /* don't cd if we already did it */ ++ if (!changedir) ++ docd(path); ++ } else { ++ mch_dirname(IObuff, IOSIZE); ++ char_u *fname = shorten_fname((char_u *)path.Path(), IObuff); ++ if (fname == NULL) ++ fname = (char_u *)path.Path(); ++ fnames[fname_index++] = vim_strsave(fname); ++ //fprintf(stderr, "%s\n", fname); ++ } ++ ++ /* Only do it for the first file/dir */ ++ changedir = false; ++ } ++ } ++ break; ++ case B_ARGV_RECEIVED: ++ //fprintf(stderr, "case B_ARGV_RECEIVED\n"); ++ for (int i = 1; i < count; ++i) ++ { ++ char *fname; ++ ++ if (m->FindString("argv", i, (const char **) &fname) == B_OK) { ++ fnames[fname_index++] = vim_strsave((char_u *)fname); ++ } ++ } ++ break; ++ default: ++ //fprintf(stderr, "case default\n"); ++ break; ++ } ++ ++ delete m; ++ ++ /* Handle the drop, :edit to get to the file */ ++ if (fname_index > 0) { ++ handle_drop(fname_index, fnames, FALSE); ++ ++ /* Update the screen display */ ++ update_screen(NOT_VALID); ++ setcursor(); ++ out_flush(); ++ } else { ++ vim_free(fnames); ++ } ++} ++ ++VimApp::VimApp(const char *appsig): ++ BApplication(appsig), ++ fFilePanelSem(-1), ++ fOpenPanel(B_OPEN_PANEL, NULL, NULL, 0, false, ++ new BMessage('open'), NULL, true), ++ fSavePanel(B_SAVE_PANEL, NULL, NULL, 0, false, ++ new BMessage('save'), NULL, true) ++{ ++} ++ ++VimApp::~VimApp() ++{ ++} ++ ++ void ++VimApp::ReadyToRun() ++{ ++ /* ++ * Apparently signals are inherited by the created thread - ++ * disable the most annoying ones. ++ */ ++ signal(SIGINT, SIG_IGN); ++ signal(SIGQUIT, SIG_IGN); ++} ++ ++ void ++VimApp::ArgvReceived(int32 arg_argc, char **arg_argv) ++{ ++ if (!IsLaunching()) { ++ /* ++ * This can happen if we are set to Single or Exclusive ++ * Launch. Be nice and open the file(s). ++ */ ++ if (gui.vimWindow) ++ gui.vimWindow->Minimize(false); ++ BMessage *m = CurrentMessage(); ++ DetachCurrentMessage(); ++ SendRefs(m, true); ++ } ++} ++ ++ void ++VimApp::RefsReceived(BMessage *m) ++{ ++ /* Horrible hack!!! XXX XXX XXX ++ * The real problem is that b_start_ffc is set too late for ++ * the initial empty buffer. As a result the window will be ++ * split instead of abandoned. ++ */ ++ int limit = 15; ++ while (--limit >= 0 && (curbuf == NULL || curbuf->b_start_ffc == 0)) ++ snooze(100000); // 0.1 s ++ if (gui.vimWindow) ++ gui.vimWindow->Minimize(false); ++ DetachCurrentMessage(); ++ SendRefs(m, true); ++} ++ ++/* ++ * Pass a BMessage on to the main() thread. ++ * Caller must have detached the message. ++ */ ++ void ++VimApp::SendRefs(BMessage *m, bool changedir) ++{ ++ VimRefsMsg rm; ++ rm.message = m; ++ rm.changedir = changedir; ++ ++ write_port(gui.vdcmp, VimMsg::Refs, &rm, sizeof(rm)); ++ // calls ::RefsReceived ++} ++ ++ void ++VimApp::MessageReceived(BMessage *m) ++{ ++ switch (m->what) { ++ case 'save': ++ { ++ entry_ref refDirectory; ++ m->FindRef("directory", &refDirectory); ++ fBrowsedPath.SetTo(&refDirectory); ++ BString strName; ++ m->FindString("name", &strName); ++ fBrowsedPath.Append(strName.String()); ++ } ++ break; ++ case 'open': ++ { ++ entry_ref ref; ++ m->FindRef("refs", &ref); ++ fBrowsedPath.SetTo(&ref); ++ } ++ break; ++ case B_CANCEL: ++ { ++ BFilePanel *panel; ++ m->FindPointer("source", (void**)&panel); ++ if(fFilePanelSem != -1 && ++ (panel == &fSavePanel || panel == &fOpenPanel)) ++ { ++ delete_sem(fFilePanelSem); ++ fFilePanelSem = -1; ++ } ++ ++ } ++ break; ++ default: ++ Inherited::MessageReceived(m); ++ break; ++ } ++} ++ ++ bool ++VimApp::QuitRequested() ++{ ++ (void)Inherited::QuitRequested(); ++ return false; ++} ++ ++/* ---------------- VimWindow ---------------- */ ++ ++VimWindow::VimWindow(): ++ BWindow(BRect(40, 40, 150, 150), ++ "Vim", ++ B_TITLED_WINDOW, ++ 0, ++ B_CURRENT_WORKSPACE) ++ ++{ ++ init(); ++} ++ ++VimWindow::~VimWindow() ++{ ++ if (formView) { ++ RemoveChild(formView); ++ delete formView; ++ } ++ gui.vimWindow = NULL; ++} ++ ++ void ++VimWindow::init() ++{ ++ /* Attach the VimFormView */ ++ formView = new VimFormView(Bounds()); ++ if (formView != NULL) { ++ AddChild(formView); ++ } ++} ++ ++#if 0 // disabled in zeta patch ++ void ++VimWindow::DispatchMessage(BMessage *m, BHandler *h) ++{ ++ /* ++ * Route B_MOUSE_UP messages to MouseUp(), in ++ * a manner that should be compatible with the ++ * intended future system behaviour. ++ */ ++ switch (m->what) { ++ case B_MOUSE_UP: ++ // if (!h) h = PreferredHandler(); ++ // gcc isn't happy without this extra set of braces, complains about ++ // jump to case label crosses init of 'class BView * v' ++ // richard@whitequeen.com jul 99 ++ { ++ BView *v = dynamic_cast(h); ++ if (v) { ++ //m->PrintToStream(); ++ BPoint where; ++ m->FindPoint("where", &where); ++ v->MouseUp(where); ++ } else { ++ Inherited::DispatchMessage(m, h); ++ } ++ } ++ break; ++ default: ++ Inherited::DispatchMessage(m, h); ++ } ++} ++#endif ++ ++ void ++VimWindow::WindowActivated(bool active) ++{ ++ Inherited::WindowActivated(active); ++ /* the textArea gets the keyboard action */ ++ if (active && gui.vimTextArea) ++ gui.vimTextArea->MakeFocus(true); ++ ++ struct VimFocusMsg fm; ++ fm.active = active; ++ ++ write_port(gui.vdcmp, VimMsg::Focus, &fm, sizeof(fm)); ++} ++ ++ bool ++VimWindow::QuitRequested() ++{ ++ struct VimKeyMsg km; ++ km.length = 5; ++ memcpy((char *)km.chars, "\033:qa\r", km.length); ++ ++#ifdef FEAT_MBYTE ++ km.csi_escape = false; ++#endif ++ ++ write_port(gui.vdcmp, VimMsg::Key, &km, sizeof(km)); ++ ++ return false; ++} ++ ++/* ---------------- VimFormView ---------------- */ ++ ++VimFormView::VimFormView(BRect frame): ++ BView(frame, "VimFormView", B_FOLLOW_ALL_SIDES, ++ B_WILL_DRAW | B_FRAME_EVENTS), ++ menuBar(NULL), ++ textArea(NULL) ++{ ++ init(frame); ++} ++ ++VimFormView::~VimFormView() ++{ ++ if (menuBar) { ++ RemoveChild(menuBar); ++#ifdef never ++ // deleting the menuBar leads to SEGV on exit ++ // richard@whitequeen.com Jul 99 ++ delete menuBar; ++#endif ++ } ++ if (textArea) { ++ RemoveChild(textArea); ++ delete textArea; ++ } ++ gui.vimForm = NULL; ++} ++ ++ void ++VimFormView::init(BRect frame) ++{ ++ menuBar = new BMenuBar(BRect(0,0,-MENUBAR_MARGIN,-MENUBAR_MARGIN), ++ "VimMenuBar"); ++ ++ AddChild(menuBar); ++ ++ BRect remaining = frame; ++ textArea = new VimTextAreaView(remaining); ++ AddChild(textArea); ++ /* The textArea will be resized later when menus are added */ ++ ++ gui.vimForm = this; ++} ++ ++ void ++VimFormView::AllAttached() ++{ ++ /* ++ * Apparently signals are inherited by the created thread - ++ * disable the most annoying ones. ++ */ ++ signal(SIGINT, SIG_IGN); ++ signal(SIGQUIT, SIG_IGN); ++ ++ if (menuBar && textArea) { ++ /* ++ * Resize the textArea to fill the space left over by the menu. ++ * This is somewhat futile since it will be done again once ++ * menus are added to the menu bar. ++ */ ++ BRect remaining = Bounds(); ++ remaining.top = MenuHeight(); ++ textArea->ResizeTo(remaining.Width(), remaining.Height()); ++ textArea->MoveTo(remaining.left, remaining.top); ++ ++#ifdef FEAT_MENU ++ menuBar->ResizeTo(remaining.right, remaining.top); ++ gui.menu_height = (int) remaining.top; ++#endif ++ } ++ Inherited::AllAttached(); ++} ++ ++ void ++VimFormView::FrameResized(float new_width, float new_height) ++{ ++ struct VimResizeMsg sm; ++ int adjust_h, adjust_w; ++ ++ new_width += 1; // adjust from width to number of pixels occupied ++ new_height += 1; ++ ++ sm.width = (int) new_width; ++ sm.height = (int) new_height; ++ adjust_w = ((int)new_width - gui_get_base_width()) % gui.char_width; ++ adjust_h = ((int)new_height - gui_get_base_height()) % gui.char_height; ++ ++ if (adjust_w > 0 || adjust_h > 0) { ++ sm.width -= adjust_w; ++ sm.height -= adjust_h; ++ } ++ ++ write_port(gui.vdcmp, VimMsg::Resize, &sm, sizeof(sm)); ++ // calls gui_resize_shell(new_width, new_height); ++ ++ return; ++ ++ /* ++ * The area below the vertical scrollbar is erased to the colour ++ * set with SetViewColor() automatically, because we had set ++ * B_WILL_DRAW. Resizing the window tight around the vertical ++ * scroll bar also helps to avoid debris. ++ */ ++} ++ ++/* ---------------- VimTextAreaView ---------------- */ ++ ++VimTextAreaView::VimTextAreaView(BRect frame): ++ BView(frame, "VimTextAreaView", B_FOLLOW_ALL_SIDES, ++#ifdef FEAT_MBYTE_IME ++ B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE | B_INPUT_METHOD_AWARE), ++#else ++ B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE), ++#endif ++ mouseDragEventCount(0) ++{ ++#ifdef FEAT_MBYTE_IME ++ IMData.messenger = NULL; ++ IMData.message = NULL; ++#endif ++ init(frame); ++} ++ ++VimTextAreaView::~VimTextAreaView() ++{ ++ gui.vimTextArea = NULL; ++} ++ ++ void ++VimTextAreaView::init(BRect frame) ++{ ++ /* set up global var for fast access */ ++ gui.vimTextArea = this; ++ ++ /* ++ * Tell the app server not to erase the view: we will ++ * fill it in completely by ourselves. ++ * (Does this really work? Even if not, it won't harm either.) ++ */ ++ SetViewColor(B_TRANSPARENT_32_BIT); ++#define PEN_WIDTH 1 ++ SetPenSize(PEN_WIDTH); ++} ++ ++ void ++VimTextAreaView::Draw(BRect updateRect) ++{ ++ /* ++ * XXX Other ports call here: ++ * out_flush(); * make sure all output has been processed * ++ * but we can't do that, since it involves too much information ++ * that is owned by other threads... ++ */ ++ ++ /* ++ * No need to use gui.vimWindow->Lock(): we are locked already. ++ * However, it would not hurt. ++ */ ++ rgb_color rgb = GUI_TO_RGB(gui.back_pixel); ++ SetLowColor(rgb); ++ FillRect(updateRect, B_SOLID_LOW); ++ gui_redraw((int) updateRect.left, (int) updateRect.top, ++ (int) (updateRect.Width() + PEN_WIDTH), (int) (updateRect.Height() + PEN_WIDTH)); ++ ++ /* Clear the border areas if needed */ ++ SetLowColor(rgb); ++ ++ if (updateRect.left < FILL_X(0)) // left border ++ FillRect(BRect(updateRect.left, updateRect.top, ++ FILL_X(0)-PEN_WIDTH, updateRect.bottom), B_SOLID_LOW); ++ if (updateRect.top < FILL_Y(0)) // top border ++ FillRect(BRect(updateRect.left, updateRect.top, ++ updateRect.right, FILL_Y(0)-PEN_WIDTH), B_SOLID_LOW); ++ if (updateRect.right >= FILL_X(Columns)) // right border ++ FillRect(BRect(FILL_X((int)Columns), updateRect.top, ++ updateRect.right, updateRect.bottom), B_SOLID_LOW); ++ if (updateRect.bottom >= FILL_Y(Rows)) // bottom border ++ FillRect(BRect(updateRect.left, FILL_Y((int)Rows), ++ updateRect.right, updateRect.bottom), B_SOLID_LOW); ++ ++#ifdef FEAT_MBYTE_IME ++ DrawIMString(); ++#endif ++} ++ ++ void ++VimTextAreaView::KeyDown(const char *bytes, int32 numBytes) ++{ ++ struct VimKeyMsg km; ++ char_u *dest = km.chars; ++ ++ bool canHaveVimModifiers = false; ++ ++ BMessage *msg = Window()->CurrentMessage(); ++ assert(msg); ++ //msg->PrintToStream(); ++ ++ /* ++ * Convert special keys to Vim codes. ++ * I think it is better to do it in the window thread ++ * so we use at least a little bit of the potential ++ * of our 2 CPUs. Besides, due to the fantastic mapping ++ * of special keys to UTF-8, we have quite some work to ++ * do... ++ * TODO: I'm not quite happy with detection of special ++ * keys. Perhaps I should use scan codes after all... ++ */ ++ if (numBytes > 1) { ++ /* This cannot be a special key */ ++ if (numBytes > KEY_MSG_BUFSIZ) ++ numBytes = KEY_MSG_BUFSIZ; // should never happen... ??? ++ km.length = numBytes; ++ memcpy((char *)dest, bytes, numBytes); ++#ifdef FEAT_MBYTE ++ km.csi_escape = true; ++#endif ++ } else { ++ int32 scancode = 0; ++ msg->FindInt32("key", &scancode); ++ ++ int32 beModifiers = 0; ++ msg->FindInt32("modifiers", &beModifiers); ++ ++ char_u string[3]; ++ int len = 0; ++ km.length = 0; ++ ++ /* ++ * For normal, printable ASCII characters, don't look them up ++ * to check if they might be a special key. They aren't. ++ */ ++ assert(B_BACKSPACE <= 0x20); ++ assert(B_DELETE == 0x7F); ++ if (((char_u)bytes[0] <= 0x20 || (char_u)bytes[0] == 0x7F) && ++ numBytes == 1) { ++ /* ++ * Due to the great nature of Be's mapping of special keys, ++ * viz. into the range of the control characters, ++ * we can only be sure it is *really* a special key if ++ * if it is special without using ctrl. So, only if ctrl is ++ * used, we need to check it unmodified. ++ */ ++ if (beModifiers & B_CONTROL_KEY) { ++ int index = keyMap->normal_map[scancode]; ++ int newNumBytes = keyMapChars[index]; ++ char_u *newBytes = (char_u *)&keyMapChars[index + 1]; ++ ++ /* ++ * Check if still special without the control key. ++ * This is needed for BACKSPACE: that key does produce ++ * different values with modifiers (DEL). ++ * Otherwise we could simply have checked for equality. ++ */ ++ if (newNumBytes != 1 || (*newBytes > 0x20 && ++ *newBytes != 0x7F )) { ++ goto notspecial; ++ } ++ bytes = (char *)newBytes; ++ } ++ canHaveVimModifiers = true; ++ ++ uint16 beoskey; ++ int first, last; ++ ++ /* ++ * If numBytes == 0 that probably always indicates a special key. ++ * (does not happen yet) ++ */ ++ if (numBytes == 0 || bytes[0] == B_FUNCTION_KEY) { ++ beoskey = F(scancode); ++ first = FIRST_FUNCTION_KEY; ++ last = NUM_SPECIAL_KEYS; ++ } else if (*bytes == '\n' && scancode == 0x47) { ++ /* remap the (non-keypad) ENTER key from \n to \r. */ ++ string[0] = '\r'; ++ len = 1; ++ first = last = 0; ++ } else { ++ beoskey = K(bytes[0]); ++ first = 0; ++ last = FIRST_FUNCTION_KEY; ++ } ++ ++ for (int i = first; i < last; i++) { ++ if (special_keys[i].BeKeys == beoskey) { ++ string[0] = CSI; ++ string[1] = special_keys[i].vim_code0; ++ string[2] = special_keys[i].vim_code1; ++ len = 3; ++ } ++ } ++ } ++notspecial: ++ if (len == 0) { ++ string[0] = bytes[0]; ++ len = 1; ++ } ++ ++ /* Special keys (and a few others) may have modifiers */ ++#if 0 ++ if (len == 3 || ++ bytes[0] == B_SPACE || bytes[0] == B_TAB || ++ bytes[0] == B_RETURN || bytes[0] == '\r' || ++ bytes[0] == B_ESCAPE) ++#else ++ if (canHaveVimModifiers) ++#endif ++ { ++ int modifiers; ++ modifiers = 0; ++ if (beModifiers & B_SHIFT_KEY) ++ modifiers |= MOD_MASK_SHIFT; ++ if (beModifiers & B_CONTROL_KEY) ++ modifiers |= MOD_MASK_CTRL; ++ if (beModifiers & B_OPTION_KEY) ++ modifiers |= MOD_MASK_ALT; ++ ++ /* ++ * For some keys a shift modifier is translated into another key ++ * code. Do we need to handle the case where len != 1 and ++ * string[0] != CSI? (Not for BeOS, since len == 3 implies ++ * string[0] == CSI...) ++ */ ++ int key; ++ if (string[0] == CSI && len == 3) ++ key = TO_SPECIAL(string[1], string[2]); ++ else ++ key = string[0]; ++ key = simplify_key(key, &modifiers); ++ if (IS_SPECIAL(key)) ++ { ++ string[0] = CSI; ++ string[1] = K_SECOND(key); ++ string[2] = K_THIRD(key); ++ len = 3; ++ } ++ else ++ { ++ string[0] = key; ++ len = 1; ++ } ++ ++ if (modifiers) ++ { ++ *dest++ = CSI; ++ *dest++ = KS_MODIFIER; ++ *dest++ = modifiers; ++ km.length = 3; ++ } ++ } ++ memcpy((char *)dest, string, len); ++ km.length += len; ++#ifdef FEAT_MBYTE ++ km.csi_escape = false; ++#endif ++ } ++ ++ write_port(gui.vdcmp, VimMsg::Key, &km, sizeof(km)); ++ ++ /* ++ * blank out the pointer if necessary ++ */ ++ if (p_mh && !gui.pointer_hidden) ++ { ++ guiBlankMouse(true); ++ gui.pointer_hidden = TRUE; ++ } ++} ++void ++VimTextAreaView::guiSendMouseEvent( ++ int button, ++ int x, ++ int y, ++ int repeated_click, ++ int_u modifiers) ++{ ++ VimMouseMsg mm; ++ ++ mm.button = button; ++ mm.x = x; ++ mm.y = y; ++ mm.repeated_click = repeated_click; ++ mm.modifiers = modifiers; ++ ++ write_port(gui.vdcmp, VimMsg::Mouse, &mm, sizeof(mm)); ++ // calls gui_send_mouse_event() ++ ++ /* ++ * if our pointer is currently hidden, then we should show it. ++ */ ++ if (gui.pointer_hidden) ++ { ++ guiBlankMouse(false); ++ gui.pointer_hidden = FALSE; ++ } ++} ++ ++void ++VimTextAreaView::guiMouseMoved( ++ int x, ++ int y) ++{ ++ VimMouseMovedMsg mm; ++ ++ mm.x = x; ++ mm.y = y; ++ ++ write_port(gui.vdcmp, VimMsg::MouseMoved, &mm, sizeof(mm)); ++ ++ if (gui.pointer_hidden) ++ { ++ guiBlankMouse(false); ++ gui.pointer_hidden = FALSE; ++ } ++} ++ ++ void ++VimTextAreaView::guiBlankMouse(bool should_hide) ++{ ++ if (should_hide) { ++ //gui.vimApp->HideCursor(); ++ gui.vimApp->ObscureCursor(); ++ /* ++ * ObscureCursor() would even be easier, but then ++ * Vim's idea of mouse visibility does not necessarily ++ * correspond to reality. ++ */ ++ } else { ++ //gui.vimApp->ShowCursor(); ++ } ++} ++ ++ int_u ++VimTextAreaView::mouseModifiersToVim(int32 beModifiers) ++{ ++ int_u vim_modifiers = 0x0; ++ ++ if (beModifiers & B_SHIFT_KEY) ++ vim_modifiers |= MOUSE_SHIFT; ++ if (beModifiers & B_CONTROL_KEY) ++ vim_modifiers |= MOUSE_CTRL; ++ if (beModifiers & B_OPTION_KEY) /* Alt or Meta key */ ++ vim_modifiers |= MOUSE_ALT; ++ ++ return vim_modifiers; ++} ++ ++ void ++VimTextAreaView::MouseDown(BPoint point) ++{ ++ BMessage *m = Window()->CurrentMessage(); ++ assert(m); ++ ++ int32 buttons = 0; ++ m->FindInt32("buttons", &buttons); ++ ++ int vimButton; ++ ++ if (buttons & B_PRIMARY_MOUSE_BUTTON) ++ vimButton = MOUSE_LEFT; ++ else if (buttons & B_SECONDARY_MOUSE_BUTTON) ++ vimButton = MOUSE_RIGHT; ++ else if (buttons & B_TERTIARY_MOUSE_BUTTON) ++ vimButton = MOUSE_MIDDLE; ++ else ++ return; /* Unknown button */ ++ ++ vimMouseButton = 1; /* don't care which one */ ++ ++ /* Handle multiple clicks */ ++ int32 clicks = 0; ++ m->FindInt32("clicks", &clicks); ++ ++ int32 modifiers = 0; ++ m->FindInt32("modifiers", &modifiers); ++ ++ vimMouseModifiers = mouseModifiersToVim(modifiers); ++ ++ guiSendMouseEvent(vimButton, point.x, point.y, ++ clicks > 1 /* = repeated_click*/, vimMouseModifiers); ++} ++ ++ void ++VimTextAreaView::MouseUp(BPoint point) ++{ ++ vimMouseButton = 0; ++ ++ BMessage *m = Window()->CurrentMessage(); ++ assert(m); ++ //m->PrintToStream(); ++ ++ int32 modifiers = 0; ++ m->FindInt32("modifiers", &modifiers); ++ ++ vimMouseModifiers = mouseModifiersToVim(modifiers); ++ ++ guiSendMouseEvent(MOUSE_RELEASE, point.x, point.y, ++ 0 /* = repeated_click*/, vimMouseModifiers); ++ ++ Inherited::MouseUp(point); ++} ++ ++ void ++VimTextAreaView::MouseMoved(BPoint point, uint32 transit, const BMessage *message) ++{ ++ /* ++ * if our pointer is currently hidden, then we should show it. ++ */ ++ if (gui.pointer_hidden) ++ { ++ guiBlankMouse(false); ++ gui.pointer_hidden = FALSE; ++ } ++ ++ if (!vimMouseButton) { /* could also check m->"buttons" */ ++ guiMouseMoved(point.x, point.y); ++ return; ++ } ++ ++ atomic_add(&mouseDragEventCount, 1); ++ ++ /* Don't care much about "transit" */ ++ guiSendMouseEvent(MOUSE_DRAG, point.x, point.y, 0, vimMouseModifiers); ++} ++ ++ void ++VimTextAreaView::MessageReceived(BMessage *m) ++{ ++ switch (m->what) { ++ case 'menu': ++ { ++ VimMenuMsg mm; ++ mm.guiMenu = NULL; /* in case no pointer in msg */ ++ m->FindPointer("VimMenu", (void **)&mm.guiMenu); ++ ++ write_port(gui.vdcmp, VimMsg::Menu, &mm, sizeof(mm)); ++ } ++ break; ++ case B_MOUSE_WHEEL_CHANGED: ++ { ++ VimScrollBar* scb = curwin->w_scrollbars[1].id; ++ float small=0, big=0, dy=0; ++ m->FindFloat("be:wheel_delta_y", &dy); ++ scb->GetSteps(&small, &big); ++ scb->SetValue(scb->Value()+small*dy*3); ++ scb->ValueChanged(scb->Value()); ++#if 0 ++ scb = curwin->w_scrollbars[0].id; ++ scb->GetSteps(&small, &big); ++ scb->SetValue(scb->Value()+small*dy); ++ scb->ValueChanged(scb->Value()); ++#endif ++ } ++ break; ++#ifdef FEAT_MBYTE_IME ++ case B_INPUT_METHOD_EVENT: ++ { ++ int32 opcode; ++ m->FindInt32("be:opcode", &opcode); ++ switch(opcode) ++ { ++ case B_INPUT_METHOD_STARTED: ++ if(!IMData.messenger) delete IMData.messenger; ++ IMData.messenger = new BMessenger(); ++ m->FindMessenger("be:reply_to", IMData.messenger); ++ break; ++ case B_INPUT_METHOD_CHANGED: ++ { ++ BString str; ++ bool confirmed; ++ if(IMData.message) *(IMData.message) = *m; ++ else IMData.message = new BMessage(*m); ++ DrawIMString(); ++ m->FindBool("be:confirmed", &confirmed); ++ if (confirmed) ++ { ++ m->FindString("be:string", &str); ++ char_u *chars = (char_u*)str.String(); ++ struct VimKeyMsg km; ++ km.csi_escape = true; ++ int clen; ++ int i = 0; ++ while (i < str.Length()) ++ { ++ clen = utf_ptr2len(chars+i); ++ memcpy(km.chars, chars+i, clen); ++ km.length = clen; ++ write_port(gui.vdcmp, VimMsg::Key, &km, sizeof(km)); ++ i += clen; ++ } ++ } ++ } ++ break; ++ case B_INPUT_METHOD_LOCATION_REQUEST: ++ { ++ BMessage msg(B_INPUT_METHOD_EVENT); ++ msg.AddInt32("be:opcode", B_INPUT_METHOD_LOCATION_REQUEST); ++ msg.AddPoint("be:location_reply", IMData.location); ++ msg.AddFloat("be:height_reply", FILL_Y(1)); ++ IMData.messenger->SendMessage(&msg); ++ } ++ break; ++ case B_INPUT_METHOD_STOPPED: ++ delete IMData.messenger; ++ delete IMData.message; ++ IMData.messenger = NULL; ++ IMData.message = NULL; ++ break; ++ } ++ } ++ //TODO: sz: break here??? ++#endif ++ default: ++ if (m->WasDropped()) { ++ BWindow *w = Window(); ++ w->DetachCurrentMessage(); ++ w->Minimize(false); ++ VimApp::SendRefs(m, (modifiers() & B_SHIFT_KEY) != 0); ++ } else { ++ Inherited::MessageReceived(m); ++ } ++ break; ++ } ++} ++ ++ int ++VimTextAreaView::mchInitFont(char_u *name) ++{ ++ VimFont *newFont = (VimFont *)gui_mch_get_font(name, 0); ++ if(newFont != NOFONT) { ++ gui.norm_font = (GuiFont)newFont; ++ gui_mch_set_font((GuiFont)newFont); ++ if (name) ++ hl_set_font_name(name); ++ ++ SetDrawingMode(B_OP_COPY); ++ ++ /* ++ * Try to load other fonts for bold, italic, and bold-italic. ++ * We should also try to work out what font to use for these when they are ++ * not specified by X resources, but we don't yet. ++ */ ++ return OK; ++ } ++ return FAIL; ++} ++ ++ void ++VimTextAreaView::mchDrawString(int row, int col, char_u *s, int len, int flags) ++{ ++ /* ++ * First we must erase the area, because DrawString won't do ++ * that for us. XXX Most of the time this is a waste of effort ++ * since the bachground has been erased already... DRAW_TRANSP ++ * should be set when appropriate!!! ++ * (Rectangles include the bottom and right edge) ++ */ ++ if (!(flags & DRAW_TRANSP)) { ++ int cells; ++#ifdef FEAT_MBYTE ++ cells = 0; ++ for(int i=0; iGetFont(&font); ++ if(!font.IsFixed()) ++ { ++ char* p = (char*)s; ++ int32 clen, lastpos = 0; ++ BPoint where; ++ int cells; ++ while((p - (char*)s) < len) { ++#ifdef FEAT_MBYTE ++ clen = utf_ptr2len((u_char*)p); ++#else ++ clen = 1; ++#endif ++ where.Set(TEXT_X(col+lastpos), TEXT_Y(row)); ++ DrawString(p, clen, where); ++ if (flags & DRAW_BOLD) { ++ where.x += 1.0; ++ SetDrawingMode(B_OP_BLEND); ++ DrawString(p, clen, where); ++ SetDrawingMode(B_OP_COPY); ++ } ++#ifdef FEAT_MBYTE ++ cells = utf_ptr2cells((char_u *)p); ++ if(cells<4) lastpos += cells; ++ else lastpos++; ++#else ++ lastpos++; ++#endif ++ p += clen; ++ } ++ } ++ else ++ { ++ BPoint where(TEXT_X(col), TEXT_Y(row)); ++ DrawString((char*)s, len, where); ++ if (flags & DRAW_BOLD) { ++ where.x += 1.0; ++ SetDrawingMode(B_OP_BLEND); ++ DrawString((char*)s, len, where); ++ SetDrawingMode(B_OP_COPY); ++ } ++ } ++ ++ if (flags & DRAW_UNDERL) { ++ int cells; ++#ifdef FEAT_MBYTE ++ cells = 0; ++ for(int i=0; iLock()) { ++ /* Clear one column more for when bold has spilled over */ ++ CopyBits(source, dest); ++ gui_clear_block(gui.scroll_region_bot - num_lines + 1, ++ gui.scroll_region_left, ++ gui.scroll_region_bot, gui.scroll_region_right); ++ ++ ++ gui.vimWindow->Unlock(); ++ /* ++ * The Draw() callback will be called now if some of the source ++ * bits were not in the visible region. ++ */ ++ } ++ //gui_x11_check_copy_area(); ++ // } ++} ++ ++/* ++ * mchInsertLines() Lock()s the window by itself. ++ */ ++ void ++VimTextAreaView::mchInsertLines(int row, int num_lines) ++{ ++ BRect source, dest; ++ ++ /* XXX Attempt at a hack: */ ++ gui.vimWindow->UpdateIfNeeded(); ++ source.left = FILL_X(gui.scroll_region_left); ++ source.top = FILL_Y(row); ++ source.right = FILL_X(gui.scroll_region_right + 1) - PEN_WIDTH; ++ source.bottom = FILL_Y(gui.scroll_region_bot - num_lines + 1) - PEN_WIDTH; ++ ++ dest.left = FILL_X(gui.scroll_region_left); ++ dest.top = FILL_Y(row + num_lines); ++ dest.right = FILL_X(gui.scroll_region_right + 1) - PEN_WIDTH; ++ dest.bottom = FILL_Y(gui.scroll_region_bot + 1) - PEN_WIDTH; ++ ++ if (gui.vimWindow->Lock()) { ++ /* Clear one column more for when bold has spilled over */ ++ CopyBits(source, dest); ++ gui_clear_block(row, gui.scroll_region_left, ++ row + num_lines - 1, gui.scroll_region_right); ++ ++ gui.vimWindow->Unlock(); ++ /* ++ * The Draw() callback will be called now if some of the source ++ * bits were not in the visible region. ++ * However, if we scroll too fast it can't keep up and the ++ * update region gets messed up. This seems to be because copying ++ * un-Draw()n bits does not generate Draw() calls for the copy... ++ * I moved the hack to before the CopyBits() to reduce the ++ * amount of additional waiting needed. ++ */ ++ ++ //gui_x11_check_copy_area(); ++ ++ } ++} ++ ++#ifdef FEAT_MBYTE_IME ++/* ++ * DrawIMString draws string with IMData.message. ++ */ ++void VimTextAreaView::DrawIMString(void) ++{ ++ static const rgb_color r_highlight = {255, 152, 152, 255}, ++ b_highlight = {152, 203, 255, 255}; ++ BString str; ++ const char* s; ++ int len; ++ BMessage* msg = IMData.message; ++ if (!msg) ++ return; ++ gui_redraw_block(IMData.row, 0, ++ IMData.row + IMData.count, W_WIDTH(curwin), GUI_MON_NOCLEAR); ++ bool confirmed = false; ++ msg->FindBool("be:confirmed", &confirmed); ++ if (confirmed) ++ return; ++ rgb_color hcolor = HighColor(), lcolor = LowColor(); ++ msg->FindString("be:string", &str); ++ s = str.String(); ++ len = str.Length(); ++ SetHighColor(0, 0, 0); ++ IMData.row = gui.row; ++ IMData.col = gui.col; ++ int32 sel_start = 0, sel_end = 0; ++ msg->FindInt32("be:selection", 0, &sel_start); ++ msg->FindInt32("be:selection", 1, &sel_end); ++ int clen, cn; ++ BPoint pos(IMData.col, 0); ++ BRect r; ++ BPoint where; ++ IMData.location = ConvertToScreen( ++ BPoint(FILL_X(pos.x), FILL_Y(IMData.row + pos.y))); ++ for (int i=0; i W_WIDTH(curwin)) ++ { ++ pos.y++; ++ pos.x = 0; ++ } ++ if (sel_start<=i && i= 0.0 && newValue == ignoreValue) { ++ ignoreValue = -1; ++ return; ++ } ++ ignoreValue = -1; ++ /* ++ * We want to throttle the amount of scroll messages generated. ++ * Normally I presume you won't get a new message before we've ++ * handled the previous one, but because we're passing them on this ++ * happens very quickly. So instead we keep a counter of how many ++ * scroll events there are (or will be) in the VDCMP, and the ++ * throttling happens at the receiving end. ++ */ ++ atomic_add(&scrollEventCount, 1); ++ ++ struct VimScrollBarMsg sm; ++ ++ sm.sb = this; ++ sm.value = (long) newValue; ++ sm.stillDragging = TRUE; ++ ++ write_port(gui.vdcmp, VimMsg::ScrollBar, &sm, sizeof(sm)); ++ ++ // calls gui_drag_scrollbar(sb, newValue, TRUE); ++} ++ ++/* ++ * When the mouse goes up, report that scrolling has stopped. ++ * MouseUp() is NOT called when the mouse-up occurs outside ++ * the window, even though the thumb does move while the mouse ++ * is outside... This has some funny effects... XXX ++ * So we do special processing when the window de/activates. ++ */ ++ void ++VimScrollBar::MouseUp(BPoint where) ++{ ++ //BMessage *m = Window()->CurrentMessage(); ++ //m->PrintToStream(); ++ ++ atomic_add(&scrollEventCount, 1); ++ ++ struct VimScrollBarMsg sm; ++ ++ sm.sb = this; ++ sm.value = (long) Value(); ++ sm.stillDragging = FALSE; ++ ++ write_port(gui.vdcmp, VimMsg::ScrollBar, &sm, sizeof(sm)); ++ ++ // calls gui_drag_scrollbar(sb, newValue, FALSE); ++ ++ Inherited::MouseUp(where); ++} ++ ++ void ++VimScrollBar::SetValue(float newValue) ++{ ++ if (newValue == Value()) ++ return; ++ ++ ignoreValue = newValue; ++ Inherited::SetValue(newValue); ++} ++ ++/* ---------------- VimFont ---------------- */ ++ ++VimFont::VimFont(): BFont() ++{ ++ init(); ++} ++ ++VimFont::VimFont(const VimFont *rhs): BFont(rhs) ++{ ++ init(); ++} ++ ++VimFont::VimFont(const BFont *rhs): BFont(rhs) ++{ ++ init(); ++} ++ ++VimFont::VimFont(const VimFont &rhs): BFont(rhs) ++{ ++ init(); ++} ++ ++VimFont::~VimFont() ++{ ++} ++ ++ void ++VimFont::init() ++{ ++ next = NULL; ++ refcount = 1; ++ name = NULL; ++} ++ ++/* ---------------- VimDialog ---------------- */ ++ ++#if defined(FEAT_GUI_DIALOG) ++ ++const unsigned int kVimDialogButtonMsg = 'VMDB'; ++const unsigned int kVimDialogIconStripeWidth = 30; ++const unsigned int kVimDialogButtonsSpacingX = 9; ++const unsigned int kVimDialogButtonsSpacingY = 4; ++const unsigned int kVimDialogSpacingX = 6; ++const unsigned int kVimDialogSpacingY = 10; ++const unsigned int kVimDialogMinimalWidth = 310; ++const unsigned int kVimDialogMinimalHeight = 75; ++const BRect kDefaultRect = ++BRect(0, 0, kVimDialogMinimalWidth, kVimDialogMinimalHeight); ++ ++VimDialog::VimDialog(int type, const char *title, const char *message, ++ const char *buttons, int dfltbutton, const char *textfield) ++: BWindow(kDefaultRect, title, B_TITLED_WINDOW_LOOK, B_MODAL_APP_WINDOW_FEEL, ++ B_NOT_CLOSABLE | B_NOT_RESIZABLE | ++ B_NOT_ZOOMABLE | B_NOT_MINIMIZABLE | B_ASYNCHRONOUS_CONTROLS) ++ , fDialogSem(-1) ++ , fDialogValue(dfltbutton) ++ , fMessageView(NULL) ++ , fInputControl(NULL) ++ , fInputValue(textfield) ++{ ++ // master view ++ VimDialogView* view = new VimDialogView(Bounds()); ++ if(view == NULL) { ++ return; ++ } ++ ++ if(title == NULL) { ++ SetTitle("Vim " VIM_VERSION_MEDIUM); ++ } ++ ++ AddChild(view); ++ ++ // icon ++ view->InitIcon(type); ++ ++ // buttons ++ int32 which = 1; ++ float maxButtonWidth = 0; ++ float maxButtonHeight = 0; ++ float buttonsWidth = 0; ++ float buttonsHeight = 0; ++ BString strButtons(buttons); ++ strButtons.RemoveAll("&"); ++ do { ++ int32 end = strButtons.FindFirst('\n'); ++ if(end != B_ERROR) { ++ strButtons[end] = '\0'; ++ } ++ ++ BButton *button = _CreateButton(which++, strButtons.String()); ++ view->AddChild(button); ++ fButtonsList.AddItem(button); ++ ++ maxButtonWidth = max_c(maxButtonWidth, button->Bounds().Width()); ++ maxButtonHeight = max_c(maxButtonHeight, button->Bounds().Height()); ++ buttonsWidth += button->Bounds().Width(); ++ buttonsHeight += button->Bounds().Height(); ++ ++ if(end == B_ERROR) { ++ break; ++ } ++ ++ strButtons.Remove(0, end + 1); ++ } while(true); ++ ++ int32 buttonsCount = fButtonsList.CountItems(); ++ buttonsWidth += kVimDialogButtonsSpacingX * (buttonsCount - 1); ++ buttonsHeight += kVimDialogButtonsSpacingY * (buttonsCount - 1); ++ float dialogWidth = buttonsWidth + kVimDialogIconStripeWidth + ++ kVimDialogSpacingX * 2; ++ float dialogHeight = maxButtonHeight + kVimDialogSpacingY * 3; ++ ++ /* Check 'v' flag in 'guioptions': vertical button placement. */ ++ bool vertical = (vim_strchr(p_go, GO_VERTICAL) != NULL) || ++ dialogWidth >= gui.vimWindow->Bounds().Width(); ++ if(vertical) { ++ dialogWidth -= buttonsWidth; ++ dialogWidth += maxButtonWidth; ++ dialogHeight -= maxButtonHeight; ++ dialogHeight += buttonsHeight; ++ } ++ ++ dialogWidth = max_c(dialogWidth, kVimDialogMinimalWidth); ++ ++ // message view ++ BRect rect(0, 0, dialogWidth, 0); ++ rect.left += kVimDialogIconStripeWidth + 16 + kVimDialogSpacingX; ++ rect.top += kVimDialogSpacingY; ++ rect.right -= kVimDialogSpacingX; ++ rect.bottom = rect.top; ++ fMessageView = new BTextView(rect, "_tv_", rect.OffsetByCopy(B_ORIGIN), ++ B_FOLLOW_LEFT | B_FOLLOW_TOP, B_WILL_DRAW); ++ ++ fMessageView->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); ++ rgb_color textColor = ui_color(B_PANEL_TEXT_COLOR); ++ fMessageView->SetFontAndColor(be_plain_font, B_FONT_ALL, &textColor); ++ fMessageView->SetText(message); ++ fMessageView->MakeEditable(false); ++ fMessageView->MakeSelectable(false); ++ fMessageView->SetWordWrap(true); ++ AddChild(fMessageView); ++ ++ float messageHeight = fMessageView->TextHeight(0, fMessageView->CountLines()); ++ fMessageView->ResizeBy(0, messageHeight); ++ fMessageView->SetTextRect(BRect(0, 0, rect.Width(), messageHeight)); ++ ++ dialogHeight += messageHeight; ++ ++ // input view ++ if(fInputValue != NULL) { ++ rect.top = ++ rect.bottom += messageHeight + kVimDialogSpacingY; ++ fInputControl = new BTextControl(rect, "_iv_", NULL, fInputValue, NULL, ++ B_FOLLOW_LEFT | B_FOLLOW_TOP, B_WILL_DRAW | B_NAVIGABLE | B_PULSE_NEEDED); ++ fInputControl->TextView()->SetText(fInputValue); ++ fInputControl->TextView()->SetWordWrap(false); ++ AddChild(fInputControl); ++ ++ float width = 0.f, height = 0.f; ++ fInputControl->GetPreferredSize(&width, &height); ++ fInputControl->MakeFocus(true); ++ ++ dialogHeight += height + kVimDialogSpacingY * 1.5; ++ } ++ ++ dialogHeight = max_c(dialogHeight, kVimDialogMinimalHeight); ++ ++ ResizeTo(dialogWidth, dialogHeight); ++ MoveTo((gui.vimWindow->Bounds().Width() - dialogWidth) / 2, ++ (gui.vimWindow->Bounds().Height() - dialogHeight) / 2); ++ ++ // adjust layout of buttons ++ float buttonWidth = max_c(maxButtonWidth, rect.Width() * 0.66); ++ BPoint origin(dialogWidth, dialogHeight); ++ origin.x -= kVimDialogSpacingX + (vertical ? buttonWidth : buttonsWidth); ++ origin.y -= kVimDialogSpacingY + (vertical ? buttonsHeight : maxButtonHeight); ++ ++ for(int32 i = 0 ; i < buttonsCount; i++) { ++ BButton *button = (BButton*)fButtonsList.ItemAt(i); ++ button->MoveTo(origin); ++ if(vertical) { ++ origin.y += button->Frame().Height() + kVimDialogButtonsSpacingY; ++ button->ResizeTo(buttonWidth, button->Frame().Height()); ++ } else { ++ origin.x += button->Frame().Width() + kVimDialogButtonsSpacingX; ++ } ++ if(dfltbutton == i + 1) { ++ button->MakeDefault(true); ++ button->MakeFocus(fInputControl == NULL); ++ } ++ } ++} ++ ++VimDialog::~VimDialog() ++{ ++ if(fDialogSem > B_OK) { ++ delete_sem(fDialogSem); ++ } ++ ++} ++ ++ int ++VimDialog::Go() ++{ ++ fDialogSem = create_sem(0, "VimDialogSem"); ++ if(fDialogSem < B_OK) { ++ Quit(); ++ return fDialogValue; ++ } ++ ++ Show(); ++ ++ while(acquire_sem(fDialogSem) == B_INTERRUPTED); ++ ++ int retValue = fDialogValue; ++ if(fInputValue != NULL) { ++ vim_strncpy((char_u*)fInputValue, (char_u*)fInputControl->Text(), IOSIZE - 1); ++ } ++ if(Lock()) { ++ Quit(); ++ } ++ ++ return retValue; ++} ++ ++void VimDialog::MessageReceived(BMessage *msg) ++{ ++ int32 which = 0; ++ if(msg->what != kVimDialogButtonMsg || ++ msg->FindInt32("which", &which) != B_OK) ++ { ++ return BWindow::MessageReceived(msg); ++ } ++ ++ fDialogValue = which; ++ delete_sem(fDialogSem); ++ fDialogSem = -1; ++} ++ ++BButton* VimDialog::_CreateButton(int32 which, const char* label) ++{ ++ BMessage *message = new BMessage(kVimDialogButtonMsg); ++ message->AddInt32("which", which); ++ ++ BRect rect(0, 0, 0, 0); ++ BString name; ++ name << "_b" << which << "_"; ++ ++ BButton* button = new BButton(rect, name.String(), label, message, ++ B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM); ++ ++ float width = 0.f, height = 0.f; ++ button->GetPreferredSize(&width, &height); ++ button->ResizeTo(width, height); ++ ++ return button; ++} ++ ++VimDialogView::VimDialogView(BRect frame) ++ : BView(frame, "VimDialogView", B_FOLLOW_ALL_SIDES, B_WILL_DRAW), ++ fIconBitmap(NULL) ++{ ++ SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); ++} ++ ++VimDialogView::~VimDialogView() ++{ ++ delete fIconBitmap; ++} ++ ++void VimDialogView::Draw(BRect updateRect) ++{ ++ BRect stripeRect = Bounds(); ++ stripeRect.right = kVimDialogIconStripeWidth; ++ SetHighColor(tint_color(ViewColor(), B_DARKEN_1_TINT)); ++ FillRect(stripeRect); ++ ++ if(fIconBitmap == NULL) { ++ return; ++ } ++ ++ SetDrawingMode(B_OP_ALPHA); ++ SetBlendingMode(B_PIXEL_ALPHA, B_ALPHA_OVERLAY); ++ DrawBitmapAsync(fIconBitmap, BPoint(18, 6)); ++} ++ ++void VimDialogView::InitIcon(int32 type) ++{ ++ if(type == VIM_GENERIC) { ++ return; ++ } ++ ++ app_info appInfo; ++ status_t status = gui.vimApp->GetAppInfo(&appInfo); ++ ++ //BPath path; ++ //status_t status = find_directory(B_BEOS_SERVERS_DIRECTORY, &path); ++ if(status != B_OK) { ++ fprintf(stderr, "Cannot retrieve app info:%s\n", strerror(status)); ++ return; ++ } ++ ++ //path.Append("app_server"); ++ ++ BFile file(&appInfo.ref/*path.Path()*/, O_RDONLY); ++ if(file.InitCheck() != B_OK) { ++ fprintf(stderr, "App file assignment failed:%s\n", ++ strerror(file.InitCheck())); ++ return; ++ } ++ ++ BResources resources(&file); ++ if(resources.InitCheck() != B_OK) { ++ fprintf(stderr, "App server resources assignment failed:%s\n", ++ strerror(resources.InitCheck())); ++ return; ++ } ++ ++ char *name = ""; ++ switch(type) { ++ case VIM_ERROR: name = "stop"; break; ++ case VIM_WARNING: name = "warn"; break; ++ case VIM_INFO: name = "info"; break; ++ case VIM_QUESTION: name = "idea"; break; ++ default: return; ++ } ++ ++ int32 iconSize = 32; ++ fIconBitmap = new BBitmap(BRect(0, 0, iconSize - 1, iconSize - 1), 0, B_RGBA32); ++ if(fIconBitmap == NULL || fIconBitmap->InitCheck() != B_OK) { ++ fprintf(stderr, "Icon bitmap allocation failed:%s\n", ++ (fIconBitmap == NULL) ? "null" : strerror(fIconBitmap->InitCheck())); ++ return; ++ } ++ ++ size_t size = 0; ++ const uint8* iconData = NULL; ++#if 0//def __HAIKU__ ++ // try vector icon first? ++ iconData = (const uint8*)resources.LoadResource(B_VECTOR_ICON_TYPE, name, &size); ++ if(iconData != NULL && BIconUtils::GetVectorIcon(iconData, size, fIconBitmap) == B_OK) { ++ delete iconData; ++ return; ++ } ++#endif ++ ++ // try bitmap icon now ++ iconData = (const uint8*)resources.LoadResource(B_LARGE_ICON_TYPE, name, &size); ++ if(iconData == NULL) { ++ fprintf(stderr, "Bitmap icon resource not found\n"); ++ delete fIconBitmap; ++ fIconBitmap = NULL; ++ return; ++ } ++ ++#if 0 //def __HAIKU__ ++ if(fIconBitmap->ColorSpace() != B_CMAP8) { ++ BIconUtils::ConvertFromCMAP8(iconData, iconSize, iconSize, iconSize, fIconBitmap); ++ } ++#else ++ fIconBitmap->SetBits(iconData, size, 0, B_CMAP8); ++#endif ++ ++ delete iconData; ++} ++ ++#endif /* FEAT_GUI_DIALOG */ ++ ++/* ---------------- ---------------- */ ++ ++// some global variables ++static char appsig[] = "application/x-vnd.Haiku-Vim-7"; ++key_map *keyMap; ++char *keyMapChars; ++int main_exitcode = 127; ++ ++ status_t ++gui_beos_process_event(bigtime_t timeout) ++{ ++ struct VimMsg vm; ++ long what; ++ ssize_t size; ++ ++ size = read_port_etc(gui.vdcmp, &what, &vm, sizeof(vm), ++ B_TIMEOUT, timeout); ++ ++ if (size >= 0) { ++ switch (what) { ++ case VimMsg::Key: ++ { ++ char_u *string = vm.u.Key.chars; ++ int len = vm.u.Key.length; ++ if (len == 1 && string[0] == Ctrl_chr('C')) { ++ trash_input_buf(); ++ got_int = TRUE; ++ } ++ ++#ifdef FEAT_MBYTE ++ if (vm.u.Key.csi_escape) ++#ifndef FEAT_MBYTE_IME ++ { ++ int i; ++ char_u buf[2]; ++ ++ for (i = 0; i < len; ++i) ++ { ++ add_to_input_buf(string + i, 1); ++ if (string[i] == CSI) ++ { ++ /* Turn CSI into K_CSI. */ ++ buf[0] = KS_EXTRA; ++ buf[1] = (int)KE_CSI; ++ add_to_input_buf(buf, 2); ++ } ++ } ++ } ++#else ++ add_to_input_buf_csi(string, len); ++#endif ++ else ++#endif ++ add_to_input_buf(string, len); ++ } ++ break; ++ case VimMsg::Resize: ++ gui_resize_shell(vm.u.NewSize.width, vm.u.NewSize.height); ++ break; ++ case VimMsg::ScrollBar: ++ { ++ /* ++ * If loads of scroll messages queue up, use only the last ++ * one. Always report when the scrollbar stops dragging. ++ * This is not perfect yet anyway: these events are queued ++ * yet again, this time in the keyboard input buffer. ++ */ ++ int32 oldCount = ++ atomic_add(&vm.u.Scroll.sb->scrollEventCount, -1); ++ if (oldCount <= 1 || !vm.u.Scroll.stillDragging) ++ gui_drag_scrollbar(vm.u.Scroll.sb->getGsb(), ++ vm.u.Scroll.value, vm.u.Scroll.stillDragging); ++ } ++ break; ++#if defined(FEAT_MENU) ++ case VimMsg::Menu: ++ gui_menu_cb(vm.u.Menu.guiMenu); ++ break; ++#endif ++ case VimMsg::Mouse: ++ { ++ int32 oldCount; ++ if (vm.u.Mouse.button == MOUSE_DRAG) ++ oldCount = ++ atomic_add(&gui.vimTextArea->mouseDragEventCount, -1); ++ else ++ oldCount = 0; ++ if (oldCount <= 1) ++ gui_send_mouse_event(vm.u.Mouse.button, vm.u.Mouse.x, ++ vm.u.Mouse.y, vm.u.Mouse.repeated_click, ++ vm.u.Mouse.modifiers); ++ } ++ break; ++ case VimMsg::MouseMoved: ++ { ++ gui_mouse_moved(vm.u.MouseMoved.x, vm.u.MouseMoved.y); ++ } ++ break; ++ case VimMsg::Focus: ++ gui.in_focus = vm.u.Focus.active; ++ /* XXX Signal that scrollbar dragging has stopped? ++ * This is needed because we don't get a MouseUp if ++ * that happens while outside the window... :-( ++ */ ++ if (gui.dragged_sb) { ++ gui.dragged_sb = SBAR_NONE; ++ } ++ // gui_update_cursor(TRUE, FALSE); ++ break; ++ case VimMsg::Refs: ++ ::RefsReceived(vm.u.Refs.message, vm.u.Refs.changedir); ++ break; ++ default: ++ // unrecognised message, ignore it ++ break; ++ } ++ } ++ ++ /* ++ * If size < B_OK, it is an error code. ++ */ ++ return size; ++} ++ ++/* ++ * Here are some functions to protect access to ScreenLines[] and ++ * LineOffset[]. These are used from the window thread to respond ++ * to a Draw() callback. When that occurs, the window is already ++ * locked by the system. ++ * ++ * Other code that needs to lock is any code that changes these ++ * variables. Other read-only access, or access merely to the ++ * contents of the screen buffer, need not be locked. ++ * ++ * If there is no window, don't call Lock() but do succeed. ++ */ ++ ++ int ++vim_lock_screen() ++{ ++ return !gui.vimWindow || gui.vimWindow->Lock(); ++} ++ ++ void ++vim_unlock_screen() ++{ ++ if (gui.vimWindow) ++ gui.vimWindow->Unlock(); ++} ++ ++#define RUN_BAPPLICATION_IN_NEW_THREAD 1 ++ ++#if RUN_BAPPLICATION_IN_NEW_THREAD ++ ++ int32 ++run_vimapp(void *args) ++{ ++ VimApp app(appsig); ++ ++ gui.vimApp = &app; ++ app.Run(); /* Run until Quit() called */ ++ ++ return 0; ++} ++ ++#else ++ ++ int32 ++call_main(void *args) ++{ ++ struct MainArgs *ma = (MainArgs *)args; ++ ++ return main(ma->argc, ma->argv); ++} ++#endif ++ ++/* ++ * Parse the GUI related command-line arguments. Any arguments used are ++ * deleted from argv, and *argc is decremented accordingly. This is called ++ * when vim is started, whether or not the GUI has been started. ++ */ ++ void ++gui_mch_prepare( ++ int *argc, ++ char **argv) ++{ ++ /* ++ * We don't have any command line arguments for the BeOS GUI yet, ++ * but this is an excellent place to create our Application object. ++ */ ++ if (!gui.vimApp) { ++ thread_info tinfo; ++ get_thread_info(find_thread(NULL), &tinfo); ++ ++ /* May need the port very early on to process RefsReceived() */ ++ gui.vdcmp = create_port(B_MAX_PORT_COUNT, "vim VDCMP"); ++ ++#if RUN_BAPPLICATION_IN_NEW_THREAD ++ thread_id tid = spawn_thread(run_vimapp, "vim VimApp", ++ tinfo.priority, NULL); ++ if (tid >= B_OK) { ++ resume_thread(tid); ++ } else { ++ getout(1); ++ } ++#else ++ MainArgs ma = { *argc, argv }; ++ thread_id tid = spawn_thread(call_main, "vim main()", ++ tinfo.priority, &ma); ++ if (tid >= B_OK) { ++ VimApp app(appsig); ++ ++ gui.vimApp = &app; ++ resume_thread(tid); ++ /* ++ * This is rather horrible. ++ * call_main will call main() again... ++ * There will be no infinite recursion since ++ * gui.vimApp is set now. ++ */ ++ app.Run(); /* Run until Quit() called */ ++ //fprintf(stderr, "app.Run() returned...\n"); ++ status_t dummy_exitcode; ++ (void)wait_for_thread(tid, &dummy_exitcode); ++ ++ /* ++ * This path should be the normal one taken to exit Vim. ++ * The main() thread calls mch_exit() which calls ++ * gui_mch_exit() which terminates its thread. ++ */ ++ exit(main_exitcode); ++ } ++#endif ++ } ++ /* Don't fork() when starting the GUI. Spawned threads are not ++ * duplicated with a fork(). The result is a mess. ++ */ ++ gui.dofork = FALSE; ++ /* ++ * XXX Try to determine whether we were started from ++ * the Tracker or the terminal. ++ * It would be nice to have this work, because the Tracker ++ * follows symlinks, so even if you double-click on gvim, ++ * when it is a link to vim it will still pass a command name ++ * of vim... ++ * We try here to see if stdin comes from /dev/null. If so, ++ * (or if there is an error, which should never happen) start the GUI. ++ * This does the wrong thing for vim - Go(); ++ ++ /* ++ for(size_t i = 0; i < 50; i++) { ++ snooze(1000000); ++ syslog(LOG_INFO, "vim snooze:%d\n", i); ++ } ++ */ ++#endif ++ ++} ++ ++/* ++ * Check if the GUI can be started. Called before gvimrc is sourced. ++ * Return OK or FAIL. ++ */ ++ int ++gui_mch_init_check(void) ++{ ++ return OK; /* TODO: GUI can always be started? */ ++} ++ ++/* ++ * Initialise the GUI. Create all the windows, set up all the call-backs ++ * etc. ++ */ ++ int ++gui_mch_init() ++{ ++ gui.def_norm_pixel = RGB(0x00, 0x00, 0x00); // black ++ gui.def_back_pixel = RGB(0xFF, 0xFF, 0xFF); // white ++ gui.norm_pixel = gui.def_norm_pixel; ++ gui.back_pixel = gui.def_back_pixel; ++ ++ gui.scrollbar_width = (int) B_V_SCROLL_BAR_WIDTH; ++ gui.scrollbar_height = (int) B_H_SCROLL_BAR_HEIGHT; ++#ifdef FEAT_MENU ++ gui.menu_height = 19; // initial guess - ++ // correct for my default settings ++#endif ++ gui.border_offset = 3; // coordinates are inside window borders ++ ++ if (gui.vdcmp < B_OK) ++ return FAIL; ++ get_key_map(&keyMap, &keyMapChars); ++ ++ gui.vimWindow = new VimWindow(); /* hidden and locked */ ++ if (!gui.vimWindow) ++ return FAIL; ++ ++ gui.vimWindow->Run(); /* Run() unlocks but does not show */ ++ ++ /* Get the colors from the "Normal" group (set in syntax.c or in a vimrc ++ * file) */ ++ set_normal_colors(); ++ ++ /* ++ * Check that none of the colors are the same as the background color ++ */ ++ gui_check_colors(); ++ ++ /* Get the colors for the highlight groups (gui_check_colors() might have ++ * changed them) */ ++ highlight_gui_started(); /* re-init colors and fonts */ ++ ++ gui_mch_new_colors(); /* window must exist for this */ ++ ++ return OK; ++} ++ ++/* ++ * Called when the foreground or background color has been changed. ++ */ ++ void ++gui_mch_new_colors() ++{ ++ rgb_color rgb = GUI_TO_RGB(gui.back_pixel); ++ ++ if (gui.vimWindow->Lock()) { ++ gui.vimForm->SetViewColor(rgb); ++ // Does this not have too much effect for those small rectangles? ++ gui.vimForm->Invalidate(); ++ gui.vimWindow->Unlock(); ++ } ++} ++ ++/* ++ * Open the GUI window which was created by a call to gui_mch_init(). ++ */ ++ int ++gui_mch_open() ++{ ++ if (gui_win_x != -1 && gui_win_y != -1) ++ gui_mch_set_winpos(gui_win_x, gui_win_y); ++ ++ /* Actually open the window */ ++ if (gui.vimWindow->Lock()) { ++ gui.vimWindow->Show(); ++ gui.vimWindow->Unlock(); ++ ++#if USE_THREAD_FOR_INPUT_WITH_TIMEOUT ++ /* Kill the thread that may have been created for the Terminal */ ++ beos_cleanup_read_thread(); ++#endif ++ ++ return OK; ++ } ++ ++ return FAIL; ++} ++ ++ void ++gui_mch_exit(int vim_exitcode) ++{ ++ if (gui.vimWindow) { ++ thread_id tid = gui.vimWindow->Thread(); ++ gui.vimWindow->Lock(); ++ gui.vimWindow->Quit(); ++ /* Wait until it is truely gone */ ++ int32 exitcode; ++ wait_for_thread(tid, &exitcode); ++ } ++ delete_port(gui.vdcmp); ++#if !RUN_BAPPLICATION_IN_NEW_THREAD ++ /* ++ * We are in the main() thread - quit the App thread and ++ * quit ourselves (passing on the exitcode). Use a global since the ++ * value from exit_thread() is only used if wait_for_thread() is ++ * called in time (race condition). ++ */ ++#endif ++ if (gui.vimApp) { ++ VimTextAreaView::guiBlankMouse(false); ++ ++ main_exitcode = vim_exitcode; ++#if RUN_BAPPLICATION_IN_NEW_THREAD ++ thread_id tid = gui.vimApp->Thread(); ++ int32 exitcode; ++ gui.vimApp->Lock(); ++ gui.vimApp->Quit(); ++ gui.vimApp->Unlock(); ++ wait_for_thread(tid, &exitcode); ++#else ++ gui.vimApp->Lock(); ++ gui.vimApp->Quit(); ++ gui.vimApp->Unlock(); ++ /* suicide */ ++ exit_thread(vim_exitcode); ++#endif ++ } ++ /* If we are somehow still here, let mch_exit() handle things. */ ++} ++ ++/* ++ * Get the position of the top left corner of the window. ++ */ ++ int ++gui_mch_get_winpos(int *x, int *y) ++{ ++ if (gui.vimWindow->Lock()) { ++ BRect r; ++ r = gui.vimWindow->Bounds(); ++ gui.vimWindow->Unlock(); ++ *x = (int)r.left; ++ *y = (int)r.top; ++ return OK; ++ } ++ else ++ return FAIL; ++} ++ ++/* ++ * Set the position of the top left corner of the window to the given ++ * coordinates. ++ */ ++ void ++gui_mch_set_winpos(int x, int y) ++{ ++ if (gui.vimWindow->Lock()) { ++ gui.vimWindow->MoveTo(x, y); ++ gui.vimWindow->Unlock(); ++ } ++} ++ ++/* ++ * Set the size of the window to the given width and height in pixels. ++ */ ++void ++gui_mch_set_shellsize( ++ int width, ++ int height, ++ int min_width, ++ int min_height, ++ int base_width, ++ int base_height, ++ int direction) //TODO: utilize? ++{ ++ /* ++ * We are basically given the size of the VimForm, if I understand ++ * correctly. Since it fills the window completely, this will also ++ * be the size of the window. ++ */ ++ if (gui.vimWindow->Lock()) { ++ gui.vimWindow->ResizeTo(width - PEN_WIDTH, height - PEN_WIDTH); ++ ++ /* set size limits */ ++ float minWidth, maxWidth, minHeight, maxHeight; ++ ++ gui.vimWindow->GetSizeLimits(&minWidth, &maxWidth, ++ &minHeight, &maxHeight); ++ gui.vimWindow->SetSizeLimits(min_width, maxWidth, ++ min_height, maxHeight); ++ ++ /* ++ * Set the resizing alignment depending on font size. ++ */ ++ gui.vimWindow->SetWindowAlignment( ++ B_PIXEL_ALIGNMENT, // window_alignment mode, ++ 1, // int32 h, ++ 0, // int32 hOffset = 0, ++ gui.char_width, // int32 width = 0, ++ base_width, // int32 widthOffset = 0, ++ 1, // int32 v = 0, ++ 0, // int32 vOffset = 0, ++ gui.char_height, // int32 height = 0, ++ base_height // int32 heightOffset = 0 ++ ); ++ ++ gui.vimWindow->Unlock(); ++ } ++} ++ ++void ++gui_mch_get_screen_dimensions( ++ int *screen_w, ++ int *screen_h) ++{ ++ BRect frame; ++ ++ { ++ BScreen screen(gui.vimWindow); ++ ++ if (screen.IsValid()) { ++ frame = screen.Frame(); ++ } else { ++ frame.right = 640; ++ frame.bottom = 480; ++ } ++ } ++ ++ /* XXX approximations... */ ++ *screen_w = (int) frame.right - 2 * gui.scrollbar_width - 20; ++ *screen_h = (int) frame.bottom - gui.scrollbar_height ++#ifdef FEAT_MENU ++ - gui.menu_height ++#endif ++ - 30; ++} ++ ++void ++gui_mch_set_text_area_pos( ++ int x, ++ int y, ++ int w, ++ int h) ++{ ++ if (!gui.vimTextArea) ++ return; ++ ++ if (gui.vimWindow->Lock()) { ++ gui.vimTextArea->MoveTo(x, y); ++ gui.vimTextArea->ResizeTo(w - PEN_WIDTH, h - PEN_WIDTH); ++ gui.vimWindow->Unlock(); ++ } ++} ++ ++ ++/* ++ * Scrollbar stuff: ++ */ ++ ++void ++gui_mch_enable_scrollbar( ++ scrollbar_T *sb, ++ int flag) ++{ ++ VimScrollBar *vsb = sb->id; ++ if (gui.vimWindow->Lock()) { ++ /* ++ * This function is supposed to be idempotent, but Show()/Hide() ++ * is not. Therefore we test if they are needed. ++ */ ++ if (flag) { ++ if (vsb->IsHidden()) { ++ vsb->Show(); ++ } ++ } else { ++ if (!vsb->IsHidden()) { ++ vsb->Hide(); ++ } ++ } ++ gui.vimWindow->Unlock(); ++ } ++} ++ ++void ++gui_mch_set_scrollbar_thumb( ++ scrollbar_T *sb, ++ int val, ++ int size, ++ int max) ++{ ++ if (gui.vimWindow->Lock()) { ++ VimScrollBar *s = sb->id; ++ if (max == 0) { ++ s->SetValue(0); ++ s->SetRange(0.0, 0.0); ++ } else { ++ s->SetProportion((float)size / (max + 1.0)); ++ s->SetSteps(1.0, size > 5 ? size - 2 : size); ++#ifndef SCROLL_PAST_END // really only defined in gui.c... ++ max = max + 1 - size; ++#endif ++ if (max < s->Value()) { ++ /* ++ * If the new maximum is lower than the current value, ++ * setting it would cause the value to be clipped and ++ * therefore a ValueChanged() call. ++ * We avoid this by setting the value first, because ++ * it presumably is <= max. ++ */ ++ s->SetValue(val); ++ s->SetRange(0.0, max); ++ } else { ++ /* ++ * In the other case, set the range first, since the ++ * new value might be higher than the current max. ++ */ ++ s->SetRange(0.0, max); ++ s->SetValue(val); ++ } ++ } ++ gui.vimWindow->Unlock(); ++ } ++} ++ ++void ++gui_mch_set_scrollbar_pos( ++ scrollbar_T *sb, ++ int x, ++ int y, ++ int w, ++ int h) ++{ ++ if (gui.vimWindow->Lock()) { ++ BRect winb = gui.vimWindow->Bounds(); ++ float vsbx = x, vsby = y; ++ VimScrollBar *vsb = sb->id; ++ vsb->ResizeTo(w - PEN_WIDTH, h - PEN_WIDTH); ++ if(winb.right-(x+w)MoveTo(vsbx, vsby); ++ gui.vimWindow->Unlock(); ++ } ++} ++ ++void ++gui_mch_create_scrollbar( ++ scrollbar_T *sb, ++ int orient) /* SBAR_VERT or SBAR_HORIZ */ ++{ ++ orientation posture = ++ (orient == SBAR_HORIZ) ? B_HORIZONTAL : B_VERTICAL; ++ ++ VimScrollBar *vsb = sb->id = new VimScrollBar(sb, posture); ++ if (gui.vimWindow->Lock()) { ++ vsb->SetTarget(gui.vimTextArea); ++ vsb->Hide(); ++ gui.vimForm->AddChild(vsb); ++ gui.vimWindow->Unlock(); ++ } ++} ++ ++#if defined(FEAT_WINDOWS) || defined(PROTO) ++void ++gui_mch_destroy_scrollbar( ++ scrollbar_T *sb) ++{ ++ if (gui.vimWindow->Lock()) { ++ sb->id->RemoveSelf(); ++ delete sb->id; ++ gui.vimWindow->Unlock(); ++ } ++} ++#endif ++ ++/* ++ * Cursor blink functions. ++ * ++ * This is a simple state machine: ++ * BLINK_NONE not blinking at all ++ * BLINK_OFF blinking, cursor is not shown ++ * BLINK_ON blinking, cursor is shown ++ */ ++ ++#define BLINK_NONE 0 ++#define BLINK_OFF 1 ++#define BLINK_ON 2 ++ ++static int blink_state = BLINK_NONE; ++static long_u blink_waittime = 700; ++static long_u blink_ontime = 400; ++static long_u blink_offtime = 250; ++static int blink_timer = 0; ++ ++void ++gui_mch_set_blinking( ++ long waittime, ++ long on, ++ long off) ++{ ++ /* TODO */ ++ blink_waittime = waittime; ++ blink_ontime = on; ++ blink_offtime = off; ++} ++ ++/* ++ * Stop the cursor blinking. Show the cursor if it wasn't shown. ++ */ ++ void ++gui_mch_stop_blink() ++{ ++ /* TODO */ ++ if (blink_timer != 0) ++ { ++ //XtRemoveTimeOut(blink_timer); ++ blink_timer = 0; ++ } ++ if (blink_state == BLINK_OFF) ++ gui_update_cursor(TRUE, FALSE); ++ blink_state = BLINK_NONE; ++} ++ ++/* ++ * Start the cursor blinking. If it was already blinking, this restarts the ++ * waiting time and shows the cursor. ++ */ ++ void ++gui_mch_start_blink() ++{ ++ /* TODO */ ++ if (blink_timer != 0) ++ ;//XtRemoveTimeOut(blink_timer); ++ /* Only switch blinking on if none of the times is zero */ ++ if (blink_waittime && blink_ontime && blink_offtime && gui.in_focus) ++ { ++ blink_timer = 1; //XtAppAddTimeOut(app_context, blink_waittime, ++ blink_state = BLINK_ON; ++ gui_update_cursor(TRUE, FALSE); ++ } ++} ++ ++/* ++ * Initialise vim to use the font with the given name. Return FAIL if the font ++ * could not be loaded, OK otherwise. ++ */ ++int ++gui_mch_init_font( ++ char_u *font_name, ++ int fontset) ++{ ++ if (gui.vimWindow->Lock()) ++ { ++ int rc = gui.vimTextArea->mchInitFont(font_name); ++ gui.vimWindow->Unlock(); ++ ++ return rc; ++ } ++ ++ return FAIL; ++} ++ ++ int ++gui_mch_adjust_charsize() ++{ ++ return FAIL; ++} ++ ++ ++ ++GuiFont ++gui_mch_get_font( ++ char_u *name, ++ int giveErrorIfMissing) ++{ ++ VimFont *font = NOFONT; ++ static VimFont *fontList = NULL; ++ ++ if (!gui.in_use) /* can't do this when GUI not running */ ++ return NOFONT; ++ ++ // storage for locally modified name; ++ const int buff_size = B_FONT_FAMILY_LENGTH + B_FONT_STYLE_LENGTH + 20; ++ static char font_name[buff_size] = {0}; ++ font_family family = {0}; ++ font_style style = {0}; ++ ++ if (name == 0 && be_fixed_font == 0) { ++ if(giveErrorIfMissing) ++ EMSG2("(fe0) default font is not defined", name); ++ return NOFONT; ++ } ++ ++ if (name != 0) { ++ STRNCPY(font_name, name, buff_size); ++ // replace underscores with spaces ++ char* end = 0; ++ while (end = strchr((char *)font_name, '_')) ++ *end = ' '; ++ } else { ++ be_fixed_font->GetFamilyAndStyle(&family, &style); ++ vim_snprintf((char*)font_name, buff_size, "%s/%s/%.0f", ++ family, style, be_fixed_font->Size()); ++ } ++ ++ VimFont *flp; ++ for (flp = fontList; flp; flp = flp->next) { ++ if (STRCMP(font_name, flp->name) == 0) { ++ flp->refcount++; ++ return (GuiFont)flp; ++ } ++ } ++ ++ // create font and store the name before strtok corrupt the buffer ;-) ++ font = new VimFont(); ++ font->name = vim_strsave((char_u*)font_name); ++ ++ strncpy(family, strtok(font_name, "/\0"), B_FONT_FAMILY_LENGTH); ++ ++ char* style_s = strtok(0, "/\0"); ++ if(style_s != 0) ++ strncpy(style, style_s, B_FONT_STYLE_LENGTH); ++ ++ float size = atof((style_s != 0) ? strtok(0, "/\0") : "0"); ++ ++ if(count_font_styles(family) <= 0) { ++ if (giveErrorIfMissing) ++ EMSG2("(fe0) Specified font %s is not found", font->name); ++ delete font; ++ return NOFONT; ++ } ++ ++ /* Remember font in the static list for later use */ ++ font->next = fontList; ++ fontList = font; ++ ++ font->SetFamilyAndStyle(family, style); ++ if(size > 0.f) ++ font->SetSize(size); ++ ++ font->SetSpacing(B_FIXED_SPACING); ++ font->SetEncoding(B_UNICODE_UTF8); ++ ++ return (GuiFont)font; ++} ++ ++/* ++ * Set the current text font. ++ */ ++void ++gui_mch_set_font( ++ GuiFont font) ++{ ++ if (gui.vimWindow->Lock()) { ++ VimFont *vf = (VimFont *)font; ++ ++ gui.vimTextArea->SetFont(vf); ++ ++ gui.char_width = (int) vf->StringWidth("n"); ++ font_height fh; ++ vf->GetHeight(&fh); ++ gui.char_height = (int)(fh.ascent + 0.9999) ++ + (int)(fh.descent + 0.9999) + (int)(fh.leading + 0.9999); ++ gui.char_ascent = (int)(fh.ascent + 0.9999); ++ ++ gui.vimWindow->Unlock(); ++ } ++} ++ ++/* XXX TODO This is apparently never called... */ ++void ++gui_mch_free_font( ++ GuiFont font) ++{ ++ if(font == NOFONT) ++ return; ++ VimFont *f = (VimFont *)font; ++ if (--f->refcount <= 0) { ++ if (f->refcount < 0) ++ fprintf(stderr, "VimFont: refcount < 0\n"); ++ delete f; ++ } ++} ++ ++ char_u * ++gui_mch_get_fontname(GuiFont font, char_u *name) ++{ ++ if (name == NULL) ++ return NULL; ++ return vim_strsave(name); ++} ++ ++/* ++ * Adjust gui.char_height (after 'linespace' was changed). ++ */ ++ int ++gui_mch_adjust_charheight() ++{ ++ ++ //TODO: linespace support? ++ ++//#ifdef FEAT_XFONTSET ++// if (gui.fontset != NOFONTSET) ++// { ++// gui.char_height = fontset_height((XFontSet)gui.fontset) + p_linespace; ++// gui.char_ascent = fontset_ascent((XFontSet)gui.fontset) ++// + p_linespace / 2; ++// } ++// else ++//#endif ++ { ++ VimFont *font = (VimFont *)gui.norm_font; ++ font_height fh = {0}; ++ font->GetHeight(&fh); ++ gui.char_height = (int)(fh.ascent + fh.descent + 0.5) + p_linespace; ++ gui.char_ascent = (int)(fh.ascent + 0.5) + p_linespace / 2; ++ } ++ return OK; ++} ++ ++ void ++gui_mch_getmouse(int *x, int *y) ++{ ++ fprintf(stderr, "gui_mch_getmouse"); ++ ++ /*int rootx, rooty, winx, winy; ++ Window root, child; ++ unsigned int mask; ++ ++ if (gui.wid && XQueryPointer(gui.dpy, gui.wid, &root, &child, ++ &rootx, &rooty, &winx, &winy, &mask)) { ++ *x = winx; ++ *y = winy; ++ } else*/ { ++ *x = -1; ++ *y = -1; ++ } ++} ++ ++ static int ++hex_digit(int c) ++{ ++ if (isdigit(c)) ++ return c - '0'; ++ c = TOLOWER_ASC(c); ++ if (c >= 'a' && c <= 'f') ++ return c - 'a' + 10; ++ return -1000; ++} ++ ++/* ++ * This function has been lifted from gui_w32.c and extended a bit. ++ * ++ * Return the Pixel value (color) for the given color name. ++ * Return INVALCOLOR for error. ++ */ ++guicolor_T ++gui_mch_get_color( ++ char_u *name) ++{ ++ typedef struct GuiColourTable ++ { ++ char *name; ++ guicolor_T colour; ++ } GuiColourTable; ++ ++#define NSTATIC_COLOURS 50 //32 ++#define NDYNAMIC_COLOURS 33 ++#define NCOLOURS (NSTATIC_COLOURS + NDYNAMIC_COLOURS) ++ ++ static GuiColourTable table[NCOLOURS] = ++ { ++ {"Black", RGB(0x00, 0x00, 0x00)}, ++ {"DarkGray", RGB(0x80, 0x80, 0x80)}, ++ {"DarkGrey", RGB(0x80, 0x80, 0x80)}, ++ {"Gray", RGB(0xC0, 0xC0, 0xC0)}, ++ {"Grey", RGB(0xC0, 0xC0, 0xC0)}, ++ {"LightGray", RGB(0xD3, 0xD3, 0xD3)}, ++ {"LightGrey", RGB(0xD3, 0xD3, 0xD3)}, ++ {"Gray10", RGB(0x1A, 0x1A, 0x1A)}, ++ {"Grey10", RGB(0x1A, 0x1A, 0x1A)}, ++ {"Gray20", RGB(0x33, 0x33, 0x33)}, ++ {"Grey20", RGB(0x33, 0x33, 0x33)}, ++ {"Gray30", RGB(0x4D, 0x4D, 0x4D)}, ++ {"Grey30", RGB(0x4D, 0x4D, 0x4D)}, ++ {"Gray40", RGB(0x66, 0x66, 0x66)}, ++ {"Grey40", RGB(0x66, 0x66, 0x66)}, ++ {"Gray50", RGB(0x7F, 0x7F, 0x7F)}, ++ {"Grey50", RGB(0x7F, 0x7F, 0x7F)}, ++ {"Gray60", RGB(0x99, 0x99, 0x99)}, ++ {"Grey60", RGB(0x99, 0x99, 0x99)}, ++ {"Gray70", RGB(0xB3, 0xB3, 0xB3)}, ++ {"Grey70", RGB(0xB3, 0xB3, 0xB3)}, ++ {"Gray80", RGB(0xCC, 0xCC, 0xCC)}, ++ {"Grey80", RGB(0xCC, 0xCC, 0xCC)}, ++ {"Gray90", RGB(0xE5, 0xE5, 0xE5)}, ++ {"Grey90", RGB(0xE5, 0xE5, 0xE5)}, ++ {"White", RGB(0xFF, 0xFF, 0xFF)}, ++ {"DarkRed", RGB(0x80, 0x00, 0x00)}, ++ {"Red", RGB(0xFF, 0x00, 0x00)}, ++ {"LightRed", RGB(0xFF, 0xA0, 0xA0)}, ++ {"DarkBlue", RGB(0x00, 0x00, 0x80)}, ++ {"Blue", RGB(0x00, 0x00, 0xFF)}, ++ {"LightBlue", RGB(0xA0, 0xA0, 0xFF)}, ++ {"DarkGreen", RGB(0x00, 0x80, 0x00)}, ++ {"Green", RGB(0x00, 0xFF, 0x00)}, ++ {"LightGreen", RGB(0xA0, 0xFF, 0xA0)}, ++ {"DarkCyan", RGB(0x00, 0x80, 0x80)}, ++ {"Cyan", RGB(0x00, 0xFF, 0xFF)}, ++ {"LightCyan", RGB(0xA0, 0xFF, 0xFF)}, ++ {"DarkMagenta", RGB(0x80, 0x00, 0x80)}, ++ {"Magenta", RGB(0xFF, 0x00, 0xFF)}, ++ {"LightMagenta", RGB(0xFF, 0xA0, 0xFF)}, ++ {"Brown", RGB(0x80, 0x40, 0x40)}, ++ {"Yellow", RGB(0xFF, 0xFF, 0x00)}, ++ {"LightYellow", RGB(0xFF, 0xFF, 0xA0)}, ++ {"DarkYellow", RGB(0xBB, 0xBB, 0x00)}, ++ {"SeaGreen", RGB(0x2E, 0x8B, 0x57)}, ++ {"Orange", RGB(0xFF, 0xA5, 0x00)}, ++ {"Purple", RGB(0xA0, 0x20, 0xF0)}, ++ {"SlateBlue", RGB(0x6A, 0x5A, 0xCD)}, ++ {"Violet", RGB(0xEE, 0x82, 0xEE)}, ++ }; ++ ++ static int endColour = NSTATIC_COLOURS; ++ static int newColour = NSTATIC_COLOURS; ++ ++ int r, g, b; ++ int i; ++ ++ if (name[0] == '#' && STRLEN(name) == 7) ++ { ++ /* Name is in "#rrggbb" format */ ++ r = hex_digit(name[1]) * 16 + hex_digit(name[2]); ++ g = hex_digit(name[3]) * 16 + hex_digit(name[4]); ++ b = hex_digit(name[5]) * 16 + hex_digit(name[6]); ++ if (r < 0 || g < 0 || b < 0) ++ return INVALCOLOR; ++ return RGB(r, g, b); ++ } ++ else ++ { ++ /* Check if the name is one of the colours we know */ ++ for (i = 0; i < endColour; i++) ++ if (STRICMP(name, table[i].name) == 0) ++ return table[i].colour; ++ } ++ ++ /* ++ * Last attempt. Look in the file "$VIMRUNTIME/rgb.txt". ++ */ ++ { ++#define LINE_LEN 100 ++ FILE *fd; ++ char line[LINE_LEN]; ++ char_u *fname; ++ ++ fname = expand_env_save((char_u *)"$VIMRUNTIME/rgb.txt"); ++ if (fname == NULL) ++ return INVALCOLOR; ++ ++ fd = fopen((char *)fname, "rt"); ++ vim_free(fname); ++ if (fd == NULL) ++ return INVALCOLOR; ++ ++ while (!feof(fd)) ++ { ++ int len; ++ int pos; ++ char *colour; ++ ++ fgets(line, LINE_LEN, fd); ++ len = strlen(line); ++ ++ if (len <= 1 || line[len-1] != '\n') ++ continue; ++ ++ line[len-1] = '\0'; ++ ++ i = sscanf(line, "%d %d %d %n", &r, &g, &b, &pos); ++ if (i != 3) ++ continue; ++ ++ colour = line + pos; ++ ++ if (STRICMP(colour, name) == 0) ++ { ++ fclose(fd); ++ /* ++ * Now remember this colour in the table. ++ * A LRU scheme might be better but this is simpler. ++ * Or could use a growing array. ++ */ ++ guicolor_T gcolour = RGB(r,g,b); ++ ++ vim_free(table[newColour].name); ++ table[newColour].name = (char *)vim_strsave((char_u *)colour); ++ table[newColour].colour = gcolour; ++ ++ newColour++; ++ if (newColour >= NCOLOURS) ++ newColour = NSTATIC_COLOURS; ++ if (endColour < NCOLOURS) ++ endColour = newColour; ++ ++ return gcolour; ++ } ++ } ++ ++ fclose(fd); ++ } ++ ++ return INVALCOLOR; ++} ++ ++/* ++ * Set the current text foreground color. ++ */ ++void ++gui_mch_set_fg_color( ++ guicolor_T color) ++{ ++ rgb_color rgb = GUI_TO_RGB(color); ++ if (gui.vimWindow->Lock()) { ++ gui.vimTextArea->SetHighColor(rgb); ++ gui.vimWindow->Unlock(); ++ } ++} ++ ++/* ++ * Set the current text background color. ++ */ ++void ++gui_mch_set_bg_color( ++ guicolor_T color) ++{ ++ rgb_color rgb = GUI_TO_RGB(color); ++ if (gui.vimWindow->Lock()) { ++ gui.vimTextArea->SetLowColor(rgb); ++ gui.vimWindow->Unlock(); ++ } ++} ++ ++/* ++ * Set the current text special color. ++ */ ++ void ++gui_mch_set_sp_color(guicolor_T color) ++{ ++ //prev_sp_color = color; ++} ++ ++void ++gui_mch_draw_string( ++ int row, ++ int col, ++ char_u *s, ++ int len, ++ int flags) ++{ ++ if (gui.vimWindow->Lock()) { ++ gui.vimTextArea->mchDrawString(row, col, s, len, flags); ++ gui.vimWindow->Unlock(); ++ } ++} ++ ++/* ++ * Return OK if the key with the termcap name "name" is supported. ++ */ ++int ++gui_mch_haskey( ++ char_u *name) ++{ ++ int i; ++ ++ for (i = 0; special_keys[i].BeKeys != 0; i++) ++ if (name[0] == special_keys[i].vim_code0 && ++ name[1] == special_keys[i].vim_code1) ++ return OK; ++ return FAIL; ++} ++ ++ void ++gui_mch_beep() ++{ ++ ::beep(); ++} ++ ++ void ++gui_mch_flash(int msec) ++{ ++ /* Do a visual beep by reversing the foreground and background colors */ ++ ++ if (gui.vimWindow->Lock()) { ++ BRect rect = gui.vimTextArea->Bounds(); ++ ++ gui.vimTextArea->SetDrawingMode(B_OP_INVERT); ++ gui.vimTextArea->FillRect(rect); ++ gui.vimTextArea->Sync(); ++ snooze(msec * 1000); /* wait for a few msec */ ++ gui.vimTextArea->FillRect(rect); ++ gui.vimTextArea->SetDrawingMode(B_OP_COPY); ++ gui.vimTextArea->Flush(); ++ gui.vimWindow->Unlock(); ++ } ++} ++ ++/* ++ * Invert a rectangle from row r, column c, for nr rows and nc columns. ++ */ ++void ++gui_mch_invert_rectangle( ++ int r, ++ int c, ++ int nr, ++ int nc) ++{ ++ BRect rect; ++ rect.left = FILL_X(c); ++ rect.top = FILL_Y(r); ++ rect.right = rect.left + nc * gui.char_width - PEN_WIDTH; ++ rect.bottom = rect.top + nr * gui.char_height - PEN_WIDTH; ++ ++ if (gui.vimWindow->Lock()) { ++ gui.vimTextArea->SetDrawingMode(B_OP_INVERT); ++ gui.vimTextArea->FillRect(rect); ++ gui.vimTextArea->SetDrawingMode(B_OP_COPY); ++ gui.vimWindow->Unlock(); ++ } ++} ++ ++/* ++ * Iconify the GUI window. ++ */ ++ void ++gui_mch_iconify() ++{ ++ if (gui.vimWindow->Lock()) { ++ gui.vimWindow->Minimize(true); ++ gui.vimWindow->Unlock(); ++ } ++} ++ ++#if defined(FEAT_EVAL) || defined(PROTO) ++/* ++ * Bring the Vim window to the foreground. ++ */ ++ void ++gui_mch_set_foreground() ++{ ++ /* TODO */ ++} ++#endif ++ ++/* ++ * Set the window title ++ */ ++void ++gui_mch_settitle( ++ char_u *title, ++ char_u *icon) ++{ ++ if (gui.vimWindow->Lock()) { ++ gui.vimWindow->SetTitle((char *)title); ++ gui.vimWindow->Unlock(); ++ } ++} ++ ++/* ++ * Draw a cursor without focus. ++ */ ++ void ++gui_mch_draw_hollow_cursor(guicolor_T color) ++{ ++ gui_mch_set_fg_color(color); ++ ++ BRect r; ++ r.left = FILL_X(gui.col); ++ r.top = FILL_Y(gui.row); ++#ifdef FEAT_MBYTE ++ int cells = utf_off2cells(LineOffset[gui.row] + gui.col, 100); //TODO-TODO ++ if(cells>=4) cells = 1; ++ r.right = r.left + cells*gui.char_width - PEN_WIDTH; ++#else ++ r.right = r.left + gui.char_width - PEN_WIDTH; ++#endif ++ r.bottom = r.top + gui.char_height - PEN_WIDTH; ++ ++ if (gui.vimWindow->Lock()) { ++ gui.vimTextArea->StrokeRect(r); ++ gui.vimWindow->Unlock(); ++ //gui_mch_flush(); ++ } ++} ++ ++/* ++ * Draw part of a cursor, only w pixels wide, and h pixels high. ++ */ ++void ++gui_mch_draw_part_cursor( ++ int w, ++ int h, ++ guicolor_T color) ++{ ++ gui_mch_set_fg_color(color); ++ ++ BRect r; ++ r.left = ++#ifdef FEAT_RIGHTLEFT ++ /* vertical line should be on the right of current point */ ++ CURSOR_BAR_RIGHT ? FILL_X(gui.col + 1) - w : ++#endif ++ FILL_X(gui.col); ++ r.right = r.left + w - PEN_WIDTH; ++ r.bottom = FILL_Y(gui.row + 1) - PEN_WIDTH; ++ r.top = r.bottom - h + PEN_WIDTH; ++ ++ if (gui.vimWindow->Lock()) { ++ gui.vimTextArea->FillRect(r); ++ gui.vimWindow->Unlock(); ++ //gui_mch_flush(); ++ } ++} ++ ++/* ++ * Catch up with any queued events. This may put keyboard input into the ++ * input buffer, call resize call-backs, trigger timers etc. If there is ++ * nothing in the event queue (& no timers pending), then we return ++ * immediately. ++ */ ++ void ++gui_mch_update() ++{ ++ gui_mch_flush(); ++ while (port_count(gui.vdcmp) > 0 && ++ !vim_is_input_buf_full() && ++ gui_beos_process_event(0) >= B_OK) ++ /* nothing */ ; ++} ++ ++/* ++ * GUI input routine called by gui_wait_for_chars(). Waits for a character ++ * from the keyboard. ++ * wtime == -1 Wait forever. ++ * wtime == 0 This should never happen. ++ * wtime > 0 Wait wtime milliseconds for a character. ++ * Returns OK if a character was found to be available within the given time, ++ * or FAIL otherwise. ++ */ ++int ++gui_mch_wait_for_chars( ++ int wtime) ++{ ++ int focus; ++ bigtime_t until, timeout; ++ status_t st; ++ ++ if (wtime >= 0) { ++ timeout = wtime * 1000; ++ until = system_time() + timeout; ++ } else { ++ timeout = B_INFINITE_TIMEOUT; ++ } ++ ++ focus = gui.in_focus; ++ for (;;) ++ { ++ /* Stop or start blinking when focus changes */ ++ if (gui.in_focus != focus) ++ { ++ if (gui.in_focus) ++ gui_mch_start_blink(); ++ else ++ gui_mch_stop_blink(); ++ focus = gui.in_focus; ++ } ++ ++ gui_mch_flush(); ++ /* ++ * Don't use gui_mch_update() because then we will spin-lock until a ++ * char arrives, instead we use gui_beos_process_event() to hang until ++ * an event arrives. No need to check for input_buf_full because we ++ * are returning as soon as it contains a single char. ++ */ ++ st = gui_beos_process_event(timeout); ++ ++ if (input_available()) ++ return OK; ++ if (st < B_OK) /* includes B_TIMED_OUT */ ++ return FAIL; ++ ++ /* ++ * Calculate how much longer we're willing to wait for the ++ * next event. ++ */ ++ if (wtime >= 0) { ++ timeout = until - system_time(); ++ if (timeout < 0) ++ break; ++ } ++ } ++ return FAIL; ++ ++} ++ ++/* ++ * Output routines. ++ */ ++ ++/* ++ * Flush any output to the screen. This is typically called before ++ * the app goes to sleep. ++ */ ++ void ++gui_mch_flush() ++{ ++ // does this need to lock the window? Apparently not but be safe. ++ if (gui.vimWindow->Lock()) { ++ gui.vimWindow->Flush(); ++ gui.vimWindow->Unlock(); ++ } ++ return; ++} ++ ++/* ++ * Clear a rectangular region of the screen from text pos (row1, col1) to ++ * (row2, col2) inclusive. ++ */ ++void ++gui_mch_clear_block( ++ int row1, ++ int col1, ++ int row2, ++ int col2) ++{ ++ if (gui.vimWindow->Lock()) { ++ gui.vimTextArea->mchClearBlock(row1, col1, row2, col2); ++ gui.vimWindow->Unlock(); ++ } ++} ++ ++ void ++gui_mch_clear_all() ++{ ++ if (gui.vimWindow->Lock()) { ++ gui.vimTextArea->mchClearAll(); ++ gui.vimWindow->Unlock(); ++ } ++} ++ ++/* ++ * Delete the given number of lines from the given row, scrolling up any ++ * text further down within the scroll region. ++ */ ++void ++gui_mch_delete_lines( ++ int row, ++ int num_lines) ++{ ++ gui.vimTextArea->mchDeleteLines(row, num_lines); ++} ++ ++/* ++ * Insert the given number of lines before the given row, scrolling down any ++ * following text within the scroll region. ++ */ ++void ++gui_mch_insert_lines( ++ int row, ++ int num_lines) ++{ ++ gui.vimTextArea->mchInsertLines(row, num_lines); ++} ++ ++#if defined(FEAT_MENU) || defined(PROTO) ++/* ++ * Menu stuff. ++ */ ++ ++void ++gui_mch_enable_menu( ++ int flag) ++{ ++ if (gui.vimWindow->Lock()) ++ { ++ BMenuBar *menubar = gui.vimForm->MenuBar(); ++ menubar->SetEnabled(flag); ++ gui.vimWindow->Unlock(); ++ } ++} ++ ++void ++gui_mch_set_menu_pos( ++ int x, ++ int y, ++ int w, ++ int h) ++{ ++ /* It will be in the right place anyway */ ++} ++ ++/* ++ * Add a sub menu to the menu bar. ++ */ ++void ++gui_mch_add_menu( ++ vimmenu_T *menu, ++ int idx) ++{ ++ vimmenu_T *parent = menu->parent; ++ ++ if (!menu_is_menubar(menu->name) ++ || (parent != NULL && parent->submenu_id == NULL)) ++ return; ++ ++ if (gui.vimWindow->Lock()) ++ { ++ /* Major re-write of the menu code, it was failing with memory corruption when ++ * we started loading multiple files (the Buffer menu) ++ * ++ * Note we don't use the preference values yet, all are inserted into the ++ * menubar on a first come-first served basis... ++ * ++ * richard@whitequeen.com jul 99 ++ */ ++ ++ BMenu *tmp; ++ ++ if ( parent ) ++ tmp = parent->submenu_id; ++ else ++ tmp = gui.vimForm->MenuBar(); ++ // make sure we don't try and add the same menu twice. The Buffers menu tries to ++ // do this and Be starts to crash... ++ ++ if ( ! tmp->FindItem((const char *) menu->dname)) { ++ ++ BMenu *bmenu = new BMenu((char *)menu->dname); ++ ++ menu->submenu_id = bmenu; ++ ++ // when we add a BMenu to another Menu, it creates the interconnecting BMenuItem ++ tmp->AddItem(bmenu); ++ ++ // Now its safe to query the menu for the associated MenuItem.... ++ menu->id = tmp->FindItem((const char *) menu->dname); ++ ++ } ++ gui.vimWindow->Unlock(); ++ } ++} ++ ++ void ++gui_mch_toggle_tearoffs(int enable) ++{ ++ /* no tearoff menus */ ++} ++ ++ static BMessage * ++MenuMessage(vimmenu_T *menu) ++{ ++ BMessage *m = new BMessage('menu'); ++ m->AddPointer("VimMenu", (void *)menu); ++ ++ return m; ++} ++ ++/* ++ * Add a menu item to a menu ++ */ ++void ++gui_mch_add_menu_item( ++ vimmenu_T *menu, ++ int idx) ++{ ++ int mnemonic = 0; ++ vimmenu_T *parent = menu->parent; ++ ++ if (parent->submenu_id == NULL) ++ return; ++ ++#ifdef never ++ /* why not add separators ? ++ * richard ++ */ ++ /* Don't add menu separator */ ++ if (menu_is_separator(menu->name)) ++ return; ++#endif ++ ++ /* TODO: use menu->actext */ ++ /* This is difficult, since on Be, an accelerator must be a single char ++ * and a lot of Vim ones are the standard VI commands. ++ * ++ * Punt for Now... ++ * richard@whiequeen.com jul 99 ++ */ ++ if (gui.vimWindow->Lock()) ++ { ++ if ( menu_is_separator(menu->name)) { ++ BSeparatorItem *item = new BSeparatorItem(); ++ parent->submenu_id->AddItem(item); ++ menu->id = item; ++ menu->submenu_id = NULL; ++ } ++ else { ++ BMenuItem *item = new BMenuItem((char *)menu->dname, ++ MenuMessage(menu)); ++ item->SetTarget(gui.vimTextArea); ++ item->SetTrigger((char) menu->mnemonic); ++ parent->submenu_id->AddItem(item); ++ menu->id = item; ++ menu->submenu_id = NULL; ++ } ++ gui.vimWindow->Unlock(); ++ } ++} ++ ++/* ++ * Destroy the machine specific menu widget. ++ */ ++void ++gui_mch_destroy_menu( ++ vimmenu_T *menu) ++{ ++ if (gui.vimWindow->Lock()) ++ { ++ assert(menu->submenu_id == NULL || menu->submenu_id->CountItems() == 0); ++ /* ++ * Detach this menu from its parent, so that it is not deleted ++ * twice once we get to delete that parent. ++ * Deleting a BMenuItem also deletes the associated BMenu, if any ++ * (which does not have any items anymore since they were ++ * removed and deleted before). ++ */ ++ BMenu *bmenu = menu->id->Menu(); ++ if (bmenu) ++ { ++ bmenu->RemoveItem(menu->id); ++ /* ++ * If we removed the last item from the menu bar, ++ * resize it out of sight. ++ */ ++ if (bmenu == gui.vimForm->MenuBar() && bmenu->CountItems() == 0) ++ { ++ bmenu->ResizeTo(-MENUBAR_MARGIN, -MENUBAR_MARGIN); ++ } ++ } ++ delete menu->id; ++ menu->id = NULL; ++ menu->submenu_id = NULL; ++ ++ gui.menu_height = (int) gui.vimForm->MenuHeight(); ++ gui.vimWindow->Unlock(); ++ } ++} ++ ++/* ++ * Make a menu either grey or not grey. ++ */ ++void ++gui_mch_menu_grey( ++ vimmenu_T *menu, ++ int grey) ++{ ++ if (menu->id != NULL) ++ menu->id->SetEnabled(!grey); ++} ++ ++/* ++ * Make menu item hidden or not hidden ++ */ ++void ++gui_mch_menu_hidden( ++ vimmenu_T *menu, ++ int hidden) ++{ ++ if (menu->id != NULL) ++ menu->id->SetEnabled(!hidden); ++} ++ ++/* ++ * This is called after setting all the menus to grey/hidden or not. ++ */ ++ void ++gui_mch_draw_menubar() ++{ ++ /* Nothing to do in BeOS */ ++} ++ ++#endif /* FEAT_MENU */ ++ ++/* Mouse stuff */ ++ ++#ifdef FEAT_CLIPBOARD ++/* ++ * Clipboard stuff, for cutting and pasting text to other windows. ++ */ ++char textplain[] = "text/plain"; ++char vimselectiontype[] = "application/x-vnd.Rhialto-Vim-selectiontype"; ++ ++/* ++ * Get the current selection and put it in the clipboard register. ++ */ ++ void ++clip_mch_request_selection(VimClipboard *cbd) ++{ ++ if (be_clipboard->Lock()) ++ { ++ BMessage *m = be_clipboard->Data(); ++ //m->PrintToStream(); ++ ++ char_u *string = NULL; ++ ssize_t stringlen = -1; ++ ++ if (m->FindData(textplain, B_MIME_TYPE, ++ (const void **)&string, &stringlen) == B_OK ++ || m->FindString("text", (const char **)&string) == B_OK) ++ { ++ if (stringlen == -1) ++ stringlen = STRLEN(string); ++ ++ int type; ++ char *seltype; ++ ssize_t seltypelen; ++ ++ /* ++ * Try to get the special vim selection type first ++ */ ++ if (m->FindData(vimselectiontype, B_MIME_TYPE, ++ (const void **)&seltype, &seltypelen) == B_OK) ++ { ++ switch (*seltype) ++ { ++ default: ++ case 'L': type = MLINE; break; ++ case 'C': type = MCHAR; break; ++#ifdef FEAT_VISUAL ++ case 'B': type = MBLOCK; break; ++#endif ++ } ++ } ++ else ++ { ++ /* Otherwise use heuristic as documented */ ++ type = memchr(string, stringlen, '\n') ? MLINE : MCHAR; ++ } ++ clip_yank_selection(type, string, (long)stringlen, cbd); ++ } ++ be_clipboard->Unlock(); ++ } ++} ++/* ++ * Make vim the owner of the current selection. ++ */ ++ void ++clip_mch_lose_selection(VimClipboard *cbd) ++{ ++ /* Nothing needs to be done here */ ++} ++ ++/* ++ * Make vim the owner of the current selection. Return OK upon success. ++ */ ++ int ++clip_mch_own_selection(VimClipboard *cbd) ++{ ++ /* ++ * Never actually own the clipboard. If another application sets the ++ * clipboard, we don't want to think that we still own it. ++ */ ++ return FAIL; ++} ++ ++/* ++ * Send the current selection to the clipboard. ++ */ ++ void ++clip_mch_set_selection(VimClipboard *cbd) ++{ ++ if (be_clipboard->Lock()) ++ { ++ be_clipboard->Clear(); ++ BMessage *m = be_clipboard->Data(); ++ assert(m); ++ ++ /* If the '*' register isn't already filled in, fill it in now */ ++ cbd->owned = TRUE; ++ clip_get_selection(cbd); ++ cbd->owned = FALSE; ++ ++ char_u *str = NULL; ++ long_u count; ++ int type; ++ ++ type = clip_convert_selection(&str, &count, cbd); ++ ++ if (type < 0) ++ return; ++ ++ m->AddData(textplain, B_MIME_TYPE, (void *)str, count); ++ ++ /* Add type of selection */ ++ char vtype; ++ switch (type) ++ { ++ default: ++ case MLINE: vtype = 'L'; break; ++ case MCHAR: vtype = 'C'; break; ++#ifdef FEAT_VISUAL ++ case MBLOCK: vtype = 'B'; break; ++#endif ++ } ++ m->AddData(vimselectiontype, B_MIME_TYPE, (void *)&vtype, 1); ++ ++ vim_free(str); ++ ++ be_clipboard->Commit(); ++ be_clipboard->Unlock(); ++ } ++} ++ ++#endif /* FEAT_CLIPBOARD */ ++ ++#ifdef FEAT_BROWSE ++/* ++ * Pop open a file browser and return the file selected, in allocated memory, ++ * or NULL if Cancel is hit. ++ * saving - TRUE if the file will be saved to, FALSE if it will be opened. ++ * title - Title message for the file browser dialog. ++ * dflt - Default name of file. ++ * ext - Default extension to be added to files without extensions. ++ * initdir - directory in which to open the browser (NULL = current dir) ++ * filter - Filter for matched files to choose from. ++ * Has a format like this: ++ * "C Files (*.c)\0*.c\0" ++ * "All Files\0*.*\0\0" ++ * If these two strings were concatenated, then a choice of two file ++ * filters will be selectable to the user. Then only matching files will ++ * be shown in the browser. If NULL, the default allows all files. ++ * ++ * *NOTE* - the filter string must be terminated with TWO nulls. ++ */ ++char_u * ++gui_mch_browse( ++ int saving, ++ char_u *title, ++ char_u *dflt, ++ char_u *ext, ++ char_u *initdir, ++ char_u *filter) ++{ ++ BFilePanel& Panel = (saving == TRUE) ? ++ gui.vimApp->fSavePanel : gui.vimApp->fOpenPanel; ++ ++ gui.vimApp->fBrowsedPath.Unset(); ++ ++ Panel.Window()->SetTitle((char*)title); ++ //if(initdir != NULL) ++ Panel.SetPanelDirectory((const char*)initdir); ++ ++ Panel.Show(); ++ ++ gui.vimApp->fFilePanelSem = create_sem(0, "FilePanelSem"); ++ ++ while(acquire_sem(gui.vimApp->fFilePanelSem) == B_INTERRUPTED); ++ ++ status_t result = gui.vimApp->fBrowsedPath.InitCheck(); ++ if(result == B_OK) { ++ return vim_strsave((char_u*)gui.vimApp->fBrowsedPath.Path()); ++ } else ++ if(result != B_NO_INIT) { ++ fprintf(stderr, "gui_mch_browse: BPath error: %#08x (%s)\n", ++ result, strerror(result)); ++ } ++ ++ return NULL; ++} ++#endif /* FEAT_BROWSE */ ++ ++ ++#if defined(FEAT_GUI_DIALOG) ++ ++/* ++ * Create a dialog dynamically from the parameter strings. ++ * type = type of dialog (question, alert, etc.) ++ * title = dialog title. may be NULL for default title. ++ * message = text to display. Dialog sizes to accommodate it. ++ * buttons = '\n' separated list of button captions, default first. ++ * dfltbutton = number of default button. ++ * ++ * This routine returns 1 if the first button is pressed, ++ * 2 for the second, etc. ++ * ++ * 0 indicates Esc was pressed. ++ * -1 for unexpected error ++ * ++ * If stubbing out this fn, return 1. ++ */ ++ ++int ++gui_mch_dialog( ++ int type, ++ char_u *title, ++ char_u *message, ++ char_u *buttons, ++ int dfltbutton, ++ char_u *textfield) ++{ ++ VimDialog *dialog = new VimDialog(type, (char*)title, (char*)message, ++ (char*)buttons, dfltbutton, (char*)textfield); ++ return dialog->Go(); ++} ++ ++#endif /* FEAT_GUI_DIALOG */ ++ ++ ++/* ++ * Return the RGB value of a pixel as long. ++ */ ++ long_u ++gui_mch_get_rgb(guicolor_T pixel) ++{ ++ rgb_color rgb = GUI_TO_RGB(pixel); ++ ++ return ((rgb.red & 0xff) << 16) + ((rgb.green & 0xff) << 8) ++ + (rgb.blue & 0xff); ++} ++ ++ void ++gui_mch_setmouse(int x, int y) ++{ ++ TRACE(); ++ /* TODO */ ++} ++ ++ void ++gui_mch_show_popupmenu(vimmenu_T *menu) ++{ ++ TRACE(); ++ /* TODO */ ++} ++ ++#ifdef FEAT_MBYTE_IME ++ void ++im_set_position(int row, int col) ++{ ++ if(gui.vimWindow->Lock()) ++ { ++ gui.vimTextArea->DrawIMString(); ++ gui.vimWindow->Unlock(); ++ } ++ return; ++} ++ ++ void ++im_set_active(int activate) ++{ ++ //TODO: ++#if 0 ++ if(activate) ++ printf("IME ON\n"); ++ else ++ printf("IME OFF\n"); ++#endif ++ return; ++} ++ ++ int ++im_get_status() ++{ ++ //TODO: ++ return(1); ++} ++#endif ++//} /* extern "C" */ +diff -Naur vim72/src/gui_beos.h vim72.haiku/src/gui_beos.h +--- vim72/src/gui_beos.h 1970-01-01 00:00:00.000000000 +0000 ++++ vim72.haiku/src/gui_beos.h 2009-04-18 09:16:27.000000000 +0000 +@@ -0,0 +1,49 @@ ++/* vi:set ts=8 sts=4 sw=4: ++ * ++ * VIM - Vi IMproved by Bram Moolenaar ++ * GUI support by Olaf "Rhialto" Seibert ++ * ++ * Do ":help uganda" in Vim to read copying and usage conditions. ++ * Do ":help credits" in Vim to see a list of people who contributed. ++ * ++ * BeOS GUI. ++ * ++ * GUI support for the Buzzword Enhanced Operating System for PPC. ++ * ++ */ ++ ++/* ++ * This file must be acceptable both as C and C++. ++ * The BeOS API is defined in terms of C++, but some classes ++ * should be somewhat known in the common C code. ++ */ ++ ++/* System classes */ ++ ++struct BMenu; ++struct BMenuItem; ++ ++/* Our own Vim-related classes */ ++ ++struct VimApp; ++struct VimFormView; ++struct VimTextAreaView; ++struct VimWindow; ++struct VimScrollBar; ++ ++/* Locking functions */ ++ ++extern int vim_lock_screen(); ++extern void vim_unlock_screen(); ++ ++#ifndef __cplusplus ++ ++typedef struct BMenu BMenu; ++typedef struct BMenuItem BMenuItem; ++typedef struct VimWindow VimWindow; ++typedef struct VimFormView VimFormView; ++typedef struct VimTextAreaView VimTextAreaView; ++typedef struct VimApp VimApp; ++typedef struct VimScrollBar VimScrollBar; ++ ++#endif +diff -Naur vim72/src/normal.c vim72.haiku/src/normal.c +--- vim72/src/normal.c 2009-04-19 20:53:33.000000000 +0000 ++++ vim72.haiku/src/normal.c 2009-04-18 09:16:31.000000000 +0000 +@@ -5280,7 +5280,8 @@ + { + if (!checkclearop(cap->oap)) + { +-#if defined(__BEOS__) && !USE_THREAD_FOR_INPUT_WITH_TIMEOUT ++#if defined(__BEOS__) || defined(__HAIKU__) ++#if !USE_THREAD_FOR_INPUT_WITH_TIMEOUT + /* + * Right now, the BeBox doesn't seem to have an easy way to detect + * window resizing, so we cheat and make the user detect it +@@ -5288,6 +5289,7 @@ + */ + ui_get_shellsize(); + #endif ++#endif + #ifdef FEAT_SYN_HL + /* Clear all syntax states to force resyncing. */ + syn_stack_free_all(curbuf); +diff -Naur vim72/src/option.h vim72.haiku/src/option.h +--- vim72/src/option.h 2009-04-19 20:53:33.000000000 +0000 ++++ vim72.haiku/src/option.h 2009-04-26 08:55:46.000000000 +0000 +@@ -9,7 +9,8 @@ + /* + * option.h: definition of global variables for settable options + */ +- ++#ifndef _OPTION_H_ ++#define _OPTION_H_ + /* + * Default values for 'errorformat'. + * The "%f|%l| %m" one is used for when the contents of the quickfix window is +@@ -1072,3 +1073,4 @@ + , WV_WRAP + , WV_COUNT /* must be the last one */ + }; ++#endif //_OPTION_H_ +diff -Naur vim72/src/os_beos.c vim72.haiku/src/os_beos.c +--- vim72/src/os_beos.c 2009-04-19 20:52:33.000000000 +0000 ++++ vim72.haiku/src/os_beos.c 2009-04-26 20:55:51.000000000 +0000 +@@ -15,6 +15,7 @@ + #include + #include + #include "vim.h" ++#include "os_beos.h" + + #if USE_THREAD_FOR_INPUT_WITH_TIMEOUT + +@@ -23,8 +24,8 @@ + #define thread_id int + #endif + +-char_u charbuf; +-signed char charcount; ++volatile char_u charbuf; ++volatile signed char charcount; + sem_id character_present; + sem_id character_wanted; + thread_id read_thread_id; +@@ -50,7 +51,7 @@ + for (;;) { + if (acquire_sem(character_wanted) != B_NO_ERROR) + break; +- charcount = read(read_cmd_fd, &charbuf, 1); ++ charcount = read(read_cmd_fd, (char_u*)&charbuf, 1); + release_sem(character_present); + } + +@@ -84,7 +85,10 @@ + struct timeval *timeout) + { + bigtime_t tmo; +- ++// TODO !!!! ++ if(gui.in_use) ++ return select(nbits, rbits, wbits, ebits, timeout); ++ + if (nbits == 0) { + /* select is purely being used for delay */ + snooze(timeout->tv_sec * 1e6 + timeout->tv_usec); +@@ -153,13 +157,15 @@ + acquired = acquire_sem(character_present); + if (acquired == B_NO_ERROR) { + if (charcount > 0) { +- add_to_input_buf(&charbuf, 1); ++ add_to_input_buf((char_u*)&charbuf, charcount); + #if !TRY_ABORT + release_sem(character_wanted); + #endif + + return 1; + } else { ++ charbuf = 0; ++ add_to_input_buf((char_u*)&charbuf, 1); + #if !TRY_ABORT + release_sem(character_wanted); + #endif +@@ -183,7 +189,7 @@ + if (acquired == B_TIMED_OUT) + acquire_sem(character_present); + if (charcount > 0) { +- add_to_input_buf(&charbuf, 1); ++ add_to_input_buf(&charbuf, charcount); + return 1; + } + return 0; +@@ -192,6 +198,17 @@ + } + #endif + ++ ++#if 0 // FEAT_GUI_BEOS ++ /* ++ * If not reading from terminal, pretend there is input. ++ * This makes the pty reading (for the GUI) "work" for ++ * :!ls but not for :r !ls ... weird. ++ */ ++ if (gui.in_use && State == EXTERNCMD) ++ return 1; ++#endif ++ + return 0; + } + +diff -Naur vim72/src/os_beos.h vim72.haiku/src/os_beos.h +--- vim72/src/os_beos.h 2009-04-19 20:52:33.000000000 +0000 ++++ vim72.haiku/src/os_beos.h 2009-04-18 09:16:37.000000000 +0000 +@@ -22,4 +22,4 @@ + + /* select emulation */ + +-#include /* for typedefs and #defines only */ ++//#include /* for typedefs and #defines only */ +diff -Naur vim72/src/os_beos.rdef vim72.haiku/src/os_beos.rdef +--- vim72/src/os_beos.rdef 1970-01-01 00:00:00.000000000 +0000 ++++ vim72.haiku/src/os_beos.rdef 2009-05-05 21:11:42.000000000 +0000 +@@ -0,0 +1,231 @@ ++/* ++ * Vim.rdef ++ */ ++ ++resource app_signature "application/x-vnd.Haiku-Vim-7"; ++ ++resource app_version { ++ major = 7, ++ middle = 2, ++ minor = 0, ++ ++ variety = B_APPV_FINAL, ++ internal = 0, ++ ++ short_info = "VIM Editor", ++ long_info = "VI Improved Editor by Bram Moolenar et al." ++}; ++ ++//resource app_flags B_SINGLE_LAUNCH; ++resource app_flags B_MULTIPLE_LAUNCH; ++ ++resource file_types message { ++ "types" = "text", ++ "types" = "text/plain", ++ "types" = "text/x-source-code", ++ "types" = "text/x-patch", ++ "types" = "text/html", ++ "types" = "text/xml", ++ "types" = "text/x-makefile", ++ "types" = "text/x-jamfile" ++}; ++ ++//#ifdef HAIKU_TARGET_PLATFORM_HAIKU ++//#else // HAIKU_TARGET_PLATFORM_HAIKU ++ ++resource large_icon array { ++ $"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0001FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" ++ $"FFFFFFFFFFFFFFFFFFFFFFFFFFFF01343500FFFFFFFFFFFFFFFFFFFFFFFFFFFF" ++ $"FFFFFF00000000000001000000003439393400FF000000000000000000FFFFFF" ++ $"FFFF001F1F1F1F1F1F1F1F1F1F1F0039393934001F1F1F1F1F1F1F1F1F00FFFF" ++ $"FFFF001F181818181818181818181800393939001F18181818181818171800FF" ++ $"FFFFFF00181818181818181818181000393939390018181818181818181000FF" ++ $"FFFFFFFF0010181818181818100F0039393939393900101818181818101000FF" ++ $"FFFFFFFF001F1818181818181000393939393939001F1818181818101000FFFF" ++ $"FFFFFFFF001F18181818181810003939393939001F1F18181818101000FFFFFF" ++ $"FFFFFFFF001F181818181818100039393939001F1F18181818101000FFFFFFFF" ++ $"FFFFFFFF001F1818191818181000393939001F1F18181818101001FFFFFFFFFF" ++ $"FFFFFFFF001F18181818181810003939001F1F181818181010003400FFFFFFFF" ++ $"FFFFFF01001F181818181818100039001F1F1818181810100039393500FFFFFF" ++ $"FFFF0135001F1818171818181000001F1F18181818101000393939393401FFFF" ++ $"FF013439001F1818181818180F001F1F19171818100F003939393939393501FF" ++ $"00353939001F181818181818101F1F1818181810100039393939393939393501" ++ $"01253939001F181818181818101F181818171010003939393939393939392500" ++ $"FF002539001F18181818181810181817181010003939393939393939392500FF" ++ $"FFFF0025001F181818181818181818180000003939393939393939392501FFFF" ++ $"FFFFFF00001F1818181818181818180017180139393939393939392500FFFFFF" ++ $"FFFFFFFF001F18181818181818181800181800393939393939392500FFFFFFFF" ++ $"FFFFFFFF001F1818181818181818100000003900000139000000000000FFFFFF" ++ $"FFFFFFFF001F181818181818181000181818001818180018181800171801FFFF" ++ $"FFFFFFFF001F18181818181810100000181800001818181818181818181801FF" ++ $"FFFFFFFF001F181818181810100000181800000018182525181800001801FFFF" ++ $"FFFFFFFF001F181818181010003900181800001817250018180000181800FFFF" ++ $"FFFFFFFF001F181818101000393900181800001818000018180000181800FFFF" ++ $"FFFFFFFF001F1818101000002500181800001818000018180000181800FFFFFF" ++ $"FFFFFFFFFF0018101100FFFF000018181800181800001818000018181801FFFF" ++ $"FFFFFFFFFFFF000000FFFFFFFF01000000250000FFFF0100FFFF010000FFFFFF" ++ $"FFFFFFFFFFFFFFFFFFFFFFFFFFFF01252501FFFFFFFFFFFFFFFFFFFFFFFFFFFF" ++ $"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" ++}; ++ ++resource mini_icon array { ++ $"FFFF00000000003434FF00000000FFFF" ++ $"FF001F1F1F1F1F0439001F1F1F1F03FF" ++ $"FF001818181818100000181818181000" ++ $"FFFF00181818100039001F18181000FF" ++ $"FFFF001818181000001F18181000FFFF" ++ $"FFFF0018181810001F1818100025FFFF" ++ $"FF3400181818101F18181000393925FF" ++ $"34390018181818180000393939393925" ++ $"00390018181818001800000039003925" ++ $"FF0000181818180000001818001800FF" ++ $"FFFF0018181800181800181818181800" ++ $"FFFF0018181800001800180018001800" ++ $"FFFF0018181039001800182518001800" ++ $"FFFF0018100000181800180018001800" ++ $"FFFFFF0000FF2500002500FF00FF00FF" ++ $"FFFFFFFFFFFFFF2525FFFFFFFFFFFFFF" ++}; ++ ++//#endif // HAIKU_TARGET_PLATFORM_HAIKU ++ ++resource(200, "info") #'ICON' array { ++ $"FFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" ++ $"FFFFFFFFFFFFFF0000252525250000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" ++ $"FFFFFFFFFFFF00252521212325252500FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" ++ $"FFFFFFFFFFFF002020BE202122232500FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" ++ $"FFFFFFFFFF002521BE3FBE212123232500FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" ++ $"FFFFFFFFFF00252120BE21212223242500FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" ++ $"FFFFFFFFFF002523212121212223242500FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" ++ $"FFFFFFFFFF002525222121232224242500FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" ++ $"FFFFFFFFFFFF00252323232324242500FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" ++ $"FFFFFFFFFF000025252424242425250000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" ++ $"FFFFFFFF00BEBE000025252525000025BE00FFFFFFFFFFFFFFFFFFFFFFFFFFFF" ++ $"FFFFFFFF009292BEBE000000002525255E00FFFFFFFFFFFFFFFFFFFFFFFFFFFF" ++ $"FFFFFFFF0021219292BE25252525BE5E2500FFFFFFFFFFFFFFFFFFFFFFFFFFFF" ++ $"FFFFFFFFFF000021219292BEBEBE5E252500FFFFFFFFFFFFFFFFFFFFFFFFFFFF" ++ $"FFFFFFFFFFFF002121212192925E25252500FFFFFFFFFFFFFFFFFFFFFFFFFFFF" ++ $"FFFFFFFFFFFF002121212121212525252500FFFFFFFFFFFFFFFFFFFFFFFFFFFF" ++ $"FFFFFFFFFFFF002121212121212525252500FFFFFFFFFFFFFFFFFFFFFFFFFFFF" ++ $"FFFFFFFFFFFF002121212121212525252500FFFFFFFFFFFFFFFFFFFFFFFFFFFF" ++ $"FFFFFFFFFF00002121212121212525252500FFFFFFFFFFFFFFFFFFFFFFFFFFFF" ++ $"FFFFFFFF00BE0021212121212125252525000EFFFFFFFFFFFFFFFFFFFFFFFFFF" ++ $"FFFFFF00BEBE0021212121212125252525000E0E0EFFFFFFFFFFFFFFFFFFFFFF" ++ $"FFFF009292BE002121212121212525252500000E0E0E0EFFFFFFFFFFFFFFFFFF" ++ $"FFFF002121920021212121212125252525BEBE00000E0E0E0EFFFFFFFFFFFFFF" ++ $"FFFF0021212121212121212121252525BEBEBEBE25000E0E0E0E0EFFFFFFFFFF" ++ $"FFFF00212121212121212121212525BEBEBEBE2525000E0E0E0E0E0E0EFFFFFF" ++ $"FFFFFF0000212121212121212125BEBEBEBE252525000E0E0E0E0E0EFFFFFFFF" ++ $"FFFFFFFFFF00002121212121219292BEBE25252525000E0E0E0E0EFFFFFFFFFF" ++ $"FFFFFFFFFFFFFF00002121212121219225252525000E0E0E0E0EFFFFFFFFFFFF" ++ $"FFFFFFFFFFFFFFFFFF00002121212121252525000E0E0E0E0EFFFFFFFFFFFFFF" ++ $"FFFFFFFFFFFFFFFFFFFFFF00002121212525000E0E0E0E0EFFFFFFFFFFFFFFFF" ++ $"FFFFFFFFFFFFFFFFFFFFFFFFFF00002125000E0E0E0E0EFFFFFFFFFFFFFFFFFF" ++ $"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000E0E0E0E0EFFFFFFFFFFFFFFFFFFFF" ++}; ++ ++resource(201, "warn") #'ICON' array { ++ $"FFFFFFFFFFFFFFFFFFFF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" ++ $"FFFFFFFFFFFFFFFFFF00FAFAFA0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" ++ $"FFFFFFFFFFFFFFFF00FAFAFAFAFAFA0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" ++ $"FFFFFFFFFFFFFF00FAFAFAFAFAFAFAFAFA0000FFFFFFFFFFFFFFFFFFFFFFFFFF" ++ $"FFFFFFFFFFFF00FAFAFAFAFAFAFAFAFAFAFAFA00FFFFFFFFFFFFFFFFFFFFFFFF" ++ $"FFFFFFFFFFFF003F3FFAFAFAFAFAFAFAFAFA3F00FFFFFFFFFFFFFFFFFFFFFFFF" ++ $"FFFFFFFFFFFF00F9F93F3FFAFAFAFAFAFA3F5D00FFFFFFFFFFFFFFFFFFFFFFFF" ++ $"FFFFFFFFFFFF00F9F9F9F93F3FFAFAFA3F5D5D00FFFFFFFFFFFFFFFFFFFFFFFF" ++ $"FFFFFFFFFFFF00F9F9F9F9F9F93F3F3F5D5D5D00FFFFFFFFFFFFFFFFFFFFFFFF" ++ $"FFFFFFFFFFFF00F9F9F9F9F9F9F9F95D5D5D5D00FFFFFFFFFFFFFFFFFFFFFFFF" ++ $"FFFFFFFFFFFF00F9F9F9F9F9F9F9F95D5D5D5D00FFFFFFFFFFFFFFFFFFFFFFFF" ++ $"FFFFFFFFFFFF00F9F9F9F9F9F9F9F95D5D5D5D00FFFFFFFFFFFFFFFFFFFFFFFF" ++ $"FFFFFFFFFFFF00F9F9F9F9F9F9F9F95D5D5D5D00FFFFFFFFFFFFFFFFFFFFFFFF" ++ $"FFFFFFFFFFFF00F9F9F9F9F9F9F9F95D5D5D5D00FFFFFFFFFFFFFFFFFFFFFFFF" ++ $"FFFFFFFFFFFF00F9F9F9F9F9F9F9F95D5D5D5D00FFFFFFFFFFFFFFFFFFFFFFFF" ++ $"FFFFFFFFFFFF00F9F9F9F9F9F9F9F95D5D5D5D00FFFFFFFFFFFFFFFFFFFFFFFF" ++ $"FFFFFFFFFFFF00F9F9F9F9F9F9F9F95D5D5D5D00FFFFFFFFFFFFFFFFFFFFFFFF" ++ $"FFFFFFFFFFFF00F9F9F9F9F9F9F9F95D5D5D5D00FFFFFFFFFFFFFFFFFFFFFFFF" ++ $"FFFFFFFFFFFFFF0000F9F9F9F9F9F95D5D5D0000FFFFFFFFFFFFFFFFFFFFFFFF" ++ $"FFFFFFFFFFFFFF00A50000F9F9F9F95D5D00FFFFFFFFFFFFFFFFFFFFFFFFFFFF" ++ $"FFFFFFFFFFFF00A5A5A5A50000F9F95D0000FFFFFFFFFFFFFFFFFFFFFFFFFFFF" ++ $"FFFFFFFFFFFF000000A5A5A5A5000000A5A50000FFFFFFFFFFFFFFFFFFFFFFFF" ++ $"FFFFFFFFFFFF00F9F90000A5A5A5A5A5A5005D00FFFFFFFFFFFFFFFFFFFFFFFF" ++ $"FFFFFFFFFFFF00F9F9F9F90000A5A5A5005D5D00FFFFFFFFFFFFFFFFFFFFFFFF" ++ $"FFFFFFFFFFFF00F9F9F9F9F9F90000005D5D5D00FFFFFFFFFFFFFFFFFFFFFFFF" ++ $"FFFFFFFFFFFF00F9F9F9F9F9F9F9F95D5D5D5D000E0EFFFFFFFFFFFFFFFFFFFF" ++ $"FFFFFFFFFFFF00F9F9F9F9F9F9F9F95D5D5D5D000E0E0E0EFFFFFFFFFFFFFFFF" ++ $"FFFFFFFFFFFF00F9F9F9F9F9F9F9F95D5D5D5D000E0E0E0E0E0EFFFFFFFFFFFF" ++ $"FFFFFFFFFFFFFF0000F9F9F9F9F9F95D5D5D000E0E0E0E0E0EFFFFFFFFFFFFFF" ++ $"FFFFFFFFFFFFFFFFFF0000F9F9F9F95D5D000E0E0E0E0E0EFFFFFFFFFFFFFFFF" ++ $"FFFFFFFFFFFFFFFFFFFFFF0000F9F95D000E0E0E0E0E0EFFFFFFFFFFFFFFFFFF" ++ $"FFFFFFFFFFFFFFFFFFFFFFFFFF0000000E0E0E0E0E0EFFFFFFFFFFFFFFFFFFFF" ++}; ++ ++resource(202, "stop") #'ICON' array { ++ $"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" ++ $"FFFFFFFFFFFFFFFFFFFFFFFFFF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" ++ $"FFFFFFFFFFFFFFFFFFFFFFFF002B2B2B0000FFFFFFFFFFFFFFFFFFFFFFFFFFFF" ++ $"FFFFFFFFFFFFFFFFFFFFFF002B2B2B2B2B2B0000FFFFFFFFFFFFFFFFFFFFFFFF" ++ $"FFFFFFFFFFFFFFFFFFFF002B2B2B2B2B2B2B2B2B0000FFFFFFFFFFFFFFFFFFFF" ++ $"FFFFFFFFFFFFFFFFFF002B2B2B2B2B2B2B2B2B2B2B2B00FFFFFFFFFFFFFFFFFF" ++ $"FFFFFFFFFFFFFFFFFF007B7B2B2B2B2B2B2B2B2B2B7B00FFFFFFFFFFFFFFFFFF" ++ $"FFFFFFFFFFFFFFFFFFFF002B7B7B2B2B2B2B2B2B7B2F00FFFFFFFFFFFFFFFFFF" ++ $"FFFFFFFFFFFFFFFFFFFF002B2B2B7B7B2B2B2B7B2F00FFFFFFFFFFFFFFFFFFFF" ++ $"FFFFFFFFFFFFFFFFFFFF002B2B2B2B2B7B7B7B2F2F00FFFFFFFFFFFFFFFFFFFF" ++ $"FFFFFFFFFFFFFFFFFFFF002B2B2B2B2B2B2B2F2F2F00FFFFFFFFFFFFFFFFFFFF" ++ $"FFFFFFFFFFFFFFFFFFFFFF002B2B2B2B2B2F2F2F00FFFFFFFFFFFFFFFFFFFFFF" ++ $"FFFFFFFFFFFFFFFFFFFFFF002B2B2B2B2B2F2F2F00FFFFFFFFFFFFFFFFFFFFFF" ++ $"FFFFFFFFFFFFFFFFFFFFFF002B2B2B2B2B2F2F00FFFFFFFFFFFFFFFFFFFFFFFF" ++ $"FFFFFFFFFFFFFFFFFFFFFFFF002B2B2B2F2F2F00FFFFFFFFFFFFFFFFFFFFFFFF" ++ $"FFFFFFFFFFFFFFFFFFFFFFFF002B2B2B2F2F2F00FFFFFFFFFFFFFFFFFFFFFFFF" ++ $"FFFFFFFFFFFFFFFFFFFFFFFF002B2B2B2F2F00FFFFFFFFFFFFFFFFFFFFFFFFFF" ++ $"FFFFFFFFFFFFFFFFFFFFFFFF002B2B2F2F2F00FFFFFFFFFFFFFFFFFFFFFFFFFF" ++ $"FFFFFFFFFFFFFFFFFFFFFFFFFF002B2F2F2F00FFFFFFFFFFFFFFFFFFFFFFFFFF" ++ $"FFFFFFFFFFFFFFFFFFFFFFFFFF002B2F2F00FFFFFFFFFFFFFFFFFFFFFFFFFFFF" ++ $"FFFFFFFFFFFFFFFFFFFFFFFFFFFF002F0000FFFFFFFFFFFFFFFFFFFFFFFFFFFF" ++ $"FFFFFFFFFFFFFFFFFFFFFFFF000000002F2F0000FFFFFFFFFFFFFFFFFFFFFFFF" ++ $"FFFFFFFFFFFFFFFFFFFFFF002D2B2B2B2D2F2F2F00FFFFFFFFFFFFFFFFFFFFFF" ++ $"FFFFFFFFFFFFFFFFFFFFFF002B2A2A2A2B2C2D2F00FFFFFFFFFFFFFFFFFFFFFF" ++ $"FFFFFFFFFFFFFFFFFFFF002D2C2A3F2A2B2B2D2D2F00FFFFFFFFFFFFFFFFFFFF" ++ $"FFFFFFFFFFFFFFFFFFFF002D2C2A2A2A2B2B2DEB2F00FFFFFFFFFFFFFFFFFFFF" ++ $"FFFFFFFFFFFFFFFFFFFF002F2D2C2B2B2C2B2DEB2F00FFFFFFFFFFFFFFFFFFFF" ++ $"FFFFFFFFFFFFFFFFFFFF002F2F2D2C2C2C2D2DEB2F00FFFFFFFFFFFFFFFFFFFF" ++ $"FFFFFFFFFFFFFFFFFFFFFF002FEB2D2D2DEBEBEB00FFFFFFFFFFFFFFFFFFFFFF" ++ $"FFFFFFFFFFFFFFFFFFFFFF002F2FEBEB2F2F2F2F00FFFFFFFFFFFFFFFFFFFFFF" ++ $"FFFFFFFFFFFFFFFFFFFFFFFF00002F2F2F2F0000FFFFFFFFFFFFFFFFFFFFFFFF" ++ $"FFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFF" ++}; ++ ++resource(203, "idea") #'ICON' array { ++ $"FFFFFFFFFFFFFFFFFF00000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" ++ $"FFFFFFFFFFFFFF0000FAFAFAFAFAFAFA0000FFFFFFFFFFFFFFFFFFFFFFFFFFFF" ++ $"FFFFFFFFFFFF00FBFAFCFCFCFCFBFCFCFAFA00FFFFFFFFFFFFFFFFFFFFFFFFFF" ++ $"FFFFFFFFFF00FAFCFCFDFDFDFDFDFDFCFBFAFA00FFFFFFFFFFFFFFFFFFFFFFFF" ++ $"FFFFFFFF00FAFDFDFDFEFEFEFEFEFEFDFCFBFAFA00FFFFFFFFFFFFFFFFFFFFFF" ++ $"FFFFFF00FAFDFCFE3F3F3F3F3FFEFEFDFDFCFBFAF900FFFFFFFFFFFFFFFFFFFF" ++ $"FFFFFF00FAFCFE3F3F3F3F3F3F3FFEFDFDFCFBFBF900FFFFFFFFFFFFFFFFFFFF" ++ $"FFFF00FAFCFDFE3F3F3F3F3F3F3F3FFEFDFDFDFBFAF900FFFFFFFFFFFFFFFFFF" ++ $"FFFF00FAFCFDFE3F3F3F3F3F3F3F3FFEFDFDFCFBFAF900FFFFFFFFFFFFFFFFFF" ++ $"FFFF00FAFCFDFE3F3F3F3F3FF93FFEFEFEFDFCFBFBF900FFFFFFFFFFFFFFFFFF" ++ $"FFFF00FAFCFDFE3F3F3F3F5D3F5D3FFEFEFDFCFBFAF900FFFFFFFFFFFFFFFFFF" ++ $"FFFF00FAFCFDFDFE3F3F3F5D3FF9FEFEFEFDFCFBFAF900FFFFFFFFFFFFFFFFFF" ++ $"FFFF00FAFCFBFDFEFE3F3F5D3FF9FEFDFDFCFCFBFAF900FFFFFFFFFFFFFFFFFF" ++ $"FFFF00FAFAFCFCFDFEFEFEFE5DF9FDFDFDFDFBFBF9F900FFFFFFFFFFFFFFFFFF" ++ $"FFFFFF00FAFBFDFDFDFEFEFDF9FDFDFCFCFBFBFAF900FFFFFFFFFFFFFFFFFFFF" ++ $"FFFFFF00FAFAFBFCFDFDFDFDF9FDFCFCFCFBFBF9F900FFFFFFFFFFFFFFFFFFFF" ++ $"FFFFFFFF00FAFAFBFCFCFDFCF9FCFCFCFBFBF9F900FFFFFFFFFFFFFFFFFFFFFF" ++ $"FFFFFFFFFF00FAFAFBFBFCFCF9FBFBFBFBF9F900FFFFFFFFFFFFFFFFFFFFFFFF" ++ $"FFFFFFFFFFFF00F9FAFBFBFBF9FBFBFAF9F900FFFFFFFFFFFFFFFFFFFFFFFFFF" ++ $"FFFFFFFFFFFFFF00F9F9FAFA5DFAF9F95D00FFFFFFFFFFFFFFFFFFFFFFFFFFFF" ++ $"FFFFFFFFFFFFFFFF005DF9FD5DF95D5D00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" ++ $"FFFFFFFFFFFFFFFF005DF9FD5DF95D5D00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" ++ $"FFFFFFFFFFFFFFFF005DF9FD5DF95D5D00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" ++ $"FFFFFFFFFFFFFFFF0000F9FD5DF95D0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" ++ $"FFFFFFFFFFFFFFFF001500000000000A00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" ++ $"FFFFFFFFFFFFFFFF00001B193F0A0A0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" ++ $"FFFFFFFFFFFFFFFF001500000000000A00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" ++ $"FFFFFFFFFFFFFFFF00001B193F0A0A0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" ++ $"FFFFFFFFFFFFFFFF001500000000000A00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" ++ $"FFFFFFFFFFFFFFFFFF001B193F0A0A000E0E0E0E0E0E0E0E0E0E0E0E0EFFFFFF" ++ $"FFFFFFFFFFFFFFFFFFFF00000000000E0E0E0E0E0E0E0E0E0E0E0E0E1BFFFFFF" ++ $"FFFFFFFFFFFFFFFFFFFFFF0000000E0E0E0E0E0E0E0E0E0E0E0E0E1B1BFFFFFF" ++}; ++ +diff -Naur vim72/src/os_unix.c vim72.haiku/src/os_unix.c +--- vim72/src/os_unix.c 2009-04-19 20:53:35.000000000 +0000 ++++ vim72.haiku/src/os_unix.c 2009-04-26 20:57:12.000000000 +0000 +@@ -51,7 +51,7 @@ + */ + #ifndef __TANDEM + # undef select +-# ifdef __BEOS__ ++# if defined(__BEOS__) || defined(__HAIKU__) + # define select beos_select + # endif + #endif +@@ -155,7 +155,7 @@ + static void may_core_dump __ARGS((void)); + + static int WaitForChar __ARGS((long)); +-#if defined(__BEOS__) ++#if defined(__BEOS__) || defined(__HAIKU__) + int RealWaitForChar __ARGS((int, long, int *)); + #else + static int RealWaitForChar __ARGS((int, long, int *)); +@@ -1094,7 +1094,7 @@ + mch_suspend() + { + /* BeOS does have SIGTSTP, but it doesn't work. */ +-#if defined(SIGTSTP) && !defined(__BEOS__) ++#if defined(SIGTSTP) && !defined(__BEOS__) && !defined(__HAIKU__) + out_flush(); /* needed to make cursor visible on some systems */ + settmode(TMODE_COOK); + out_flush(); /* needed to disable mouse on some systems */ +@@ -1966,6 +1966,11 @@ + if (gui.in_use) + type = 1; + # endif ++# ifdef FEAT_GUI_BEOS ++ /* TODO: If this means (gui.in_use) why not merge with above? (Dany) */ ++ /* we always have a 'window' */ ++ type = 1; ++# endif + #endif + + /* +@@ -1990,7 +1995,7 @@ + # endif + set_x11_title(title); /* x11 */ + #endif +-#if defined(FEAT_GUI_GTK) \ ++#if defined(FEAT_GUI_GTK) || defined(__HAIKU__)\ + || defined(FEAT_GUI_PHOTON) || defined(FEAT_GUI_MAC) + else + gui_mch_settitle(title, icon); +@@ -3033,7 +3038,9 @@ + ml_close_all(TRUE); /* remove all memfiles */ + may_core_dump(); + #ifdef FEAT_GUI ++# ifndef FEAT_GUI_BEOS /* BeOS always has GUI */ + if (gui.in_use) ++# endif + gui_exit(r); + #endif + +@@ -3865,7 +3872,7 @@ + + if (!pipe_error) /* pty or pipe opened or not used */ + { +-# ifdef __BEOS__ ++# if defined(__BEOS__) || defined(__HAIKU__) && USE_THREAD_FOR_INPUT_WITH_TIMEOUT + beos_cleanup_read_thread(); + # endif + +@@ -4673,7 +4680,7 @@ + * Or when a Linux GPM mouse event is waiting. + */ + /* ARGSUSED */ +-#if defined(__BEOS__) ++#if defined(__BEOS__) || defined(__HAIKU__) + int + #else + static int +diff -Naur vim72/src/proto/gui_beos.pro vim72.haiku/src/proto/gui_beos.pro +--- vim72/src/proto/gui_beos.pro 1970-01-01 00:00:00.000000000 +0000 ++++ vim72.haiku/src/proto/gui_beos.pro 2009-05-04 07:23:00.000000000 +0000 +@@ -0,0 +1,80 @@ ++/* gui_beos.cc - hand crafted */ ++void gui_mch_prepare __ARGS((int *argc, char **argv)); ++int gui_mch_init __ARGS((void)); ++int gui_mch_open __ARGS((void)); ++void gui_mch_exit __ARGS((int vim_exitcode)); ++int gui_mch_init_check __ARGS((void)); ++void gui_mch_flush __ARGS((void)); ++ ++void gui_mch_new_colors __ARGS((void)); ++void gui_mch_set_bg_color __ARGS((guicolor_T color)); ++void gui_mch_set_fg_color __ARGS((guicolor_T color)); ++void gui_mch_set_sp_color __ARGS((guicolor_T color)); ++long_u gui_mch_get_rgb __ARGS((guicolor_T pixel)); ++guicolor_T gui_mch_get_color __ARGS((char_u *name)); ++ ++GuiFont gui_mch_get_font __ARGS((char_u *name, int giveErrorIfMissing)); ++void gui_mch_set_font __ARGS((GuiFont font)); ++int gui_mch_init_font __ARGS((char_u* font_name, int fontset)); ++void gui_mch_free_font __ARGS((GuiFont font)); ++char_u* gui_mch_get_fontname __ARGS((GuiFont font, char_u *name)); ++ ++void gui_mch_set_winpos __ARGS((int x, int y)); ++int gui_mch_get_winpos __ARGS((int *x, int *y)); ++void gui_mch_set_shellsize __ARGS((int w, int h, int m_w, int m_h, int b_w, int b_h, int d)); ++void gui_mch_get_screen_dimensions __ARGS((int* screen_w, int* screen_h)); ++void gui_mch_set_text_area_pos __ARGS((int x, int y, int w, int h)); ++ ++void gui_mch_enable_scrollbar __ARGS((scrollbar_T* sb, int flag)); ++void gui_mch_set_scrollbar_thumb __ARGS((scrollbar_T *sb,int val, int size, int max)); ++void gui_mch_set_scrollbar_pos __ARGS((scrollbar_T *sb, int x, int y, int w, int h)); ++void gui_mch_create_scrollbar __ARGS((scrollbar_T *sb, int orient)); ++void gui_mch_destroy_scrollbar __ARGS((scrollbar_T* sb)); ++ ++void gui_mch_set_blinking __ARGS((long waittime, long on, long off)); ++void gui_mch_stop_blink __ARGS(()); ++void gui_mch_start_blink __ARGS(()); ++ ++int gui_mch_adjust_charheight __ARGS(()); ++void gui_mch_draw_string __ARGS((int row, int col, char_u* s, int len, int flags)); ++int gui_mch_haskey __ARGS((char_u* name)); ++void gui_mch_beep __ARGS(()); ++void gui_mch_flash __ARGS((int msec)); ++void gui_mch_invert_rectangle __ARGS((int r, int c, int nr, int nc)); ++void gui_mch_iconify __ARGS(()); ++void gui_mch_set_foreground __ARGS(()); ++void gui_mch_settitle __ARGS((char_u* title, char_u* icon)); ++void gui_mch_draw_hollow_cursor __ARGS((guicolor_T color)); ++void gui_mch_draw_part_cursor __ARGS((int w, int h, guicolor_T color)); ++void gui_mch_update __ARGS(()); ++int gui_mch_wait_for_chars __ARGS((int wtime)); ++void gui_mch_clear_block __ARGS((int row1, int col1, int row2, int col2)); ++void gui_mch_clear_all __ARGS(()); ++void gui_mch_delete_lines __ARGS((int row, int num_lines)); ++void gui_mch_insert_lines __ARGS((int row, int num_lines)); ++ ++void gui_mch_getmouse __ARGS((int *x, int *y)); ++void gui_mch_setmouse __ARGS((int x, int y)); ++ ++void gui_mch_enable_menu __ARGS((int flag)); ++void gui_mch_set_menu_pos __ARGS((int x, int y, int w, int h)); ++void gui_mch_add_menu __ARGS((vimmenu_T* menu, int idx)); ++void gui_mch_add_menu_item __ARGS((vimmenu_T *menu, int idx)); ++void gui_mch_destroy_menu __ARGS((vimmenu_T *menu)); ++void gui_mch_menu_grey __ARGS((vimmenu_T *menu, int grey)); ++void gui_mch_menu_hidden __ARGS((vimmenu_T *menu, int hidden)); ++void gui_mch_draw_menubar __ARGS(()); ++void gui_mch_show_popupmenu __ARGS((vimmenu_T *menu)); ++void gui_mch_toggle_tearoffs __ARGS((int enable)); ++ ++void clip_mch_request_selection __ARGS((VimClipboard *cbd)); ++void clip_mch_set_selection __ARGS((VimClipboard *cbd)); ++void clip_mch_lose_selection __ARGS((VimClipboard *cbd)); ++int clip_mch_own_selection __ARGS((VimClipboard *cbd)); ++ ++char_u* gui_mch_browse __ARGS((int saving, char_u *title, char_u *dflt, char_u *ext, char_u *initdir, char_u *filter)); ++int gui_mch_dialog __ARGS((int type, char_u *title, char_u* message, char_u *buttons, int dfltbutton, char_u* textfield)); ++ ++void im_set_position __ARGS((int row, int col)); ++void im_set_active __ARGS((int activate)); ++int im_get_status __ARGS(()); +diff -Naur vim72/src/proto/os_beos.pro vim72.haiku/src/proto/os_beos.pro +--- vim72/src/proto/os_beos.pro 1970-01-01 00:00:00.000000000 +0000 ++++ vim72.haiku/src/proto/os_beos.pro 2009-04-18 09:16:46.000000000 +0000 +@@ -0,0 +1,4 @@ ++/* os_beos.c */ ++void beos_cleanup_read_thread __ARGS((void)); ++int beos_select __ARGS((int nbits, struct fd_set *rbits, struct fd_set *wbits, struct fd_set *ebits, struct timeval *timeout)); ++/* vim: set ft=c : */ +diff -Naur vim72/src/proto.h vim72.haiku/src/proto.h +--- vim72/src/proto.h 2009-04-19 20:53:35.000000000 +0000 ++++ vim72.haiku/src/proto.h 2009-04-18 09:16:47.000000000 +0000 +@@ -59,7 +59,7 @@ + # ifdef VMS + # include "os_vms.pro" + # endif +-# ifdef __BEOS__ ++# if defined(__BEOS__) || defined(__HAIKU__) + # include "os_beos.pro" + # endif + # ifdef RISCOS +@@ -211,6 +211,9 @@ + extern char *vim_SelFile __ARGS((Widget toplevel, char *prompt, char *init_path, int (*show_entry)(), int x, int y, guicolor_T fg, guicolor_T bg, guicolor_T scroll_fg, guicolor_T scroll_bg)); + # endif + # endif ++# ifdef FEAT_GUI_BEOS ++# include "gui_beos.pro" ++# endif + # ifdef FEAT_GUI_MAC + # include "gui_mac.pro" + # endif +diff -Naur vim72/src/pty.c vim72.haiku/src/pty.c +--- vim72/src/pty.c 2009-04-19 20:53:35.000000000 +0000 ++++ vim72.haiku/src/pty.c 2009-04-18 09:16:47.000000000 +0000 +@@ -352,7 +352,7 @@ + static char PtyProto[] = "/dev/ptym/ptyXY"; + static char TtyProto[] = "/dev/pty/ttyXY"; + # else +-# ifdef __BEOS__ ++# if defined(__BEOS__) || defined(__HAIKU__) + static char PtyProto[] = "/dev/pt/XY"; + static char TtyProto[] = "/dev/tt/XY"; + # else +diff -Naur vim72/src/screen.c vim72.haiku/src/screen.c +--- vim72/src/screen.c 2009-04-19 20:53:34.000000000 +0000 ++++ vim72.haiku/src/screen.c 2009-04-18 09:16:47.000000000 +0000 +@@ -7393,6 +7393,10 @@ + + win_new_shellsize(); /* fit the windows in the new sized shell */ + ++#ifdef FEAT_GUI_BEOS ++ vim_lock_screen(); /* be safe, put it here */ ++#endif ++ + comp_col(); /* recompute columns for shown command and ruler */ + + /* +@@ -7624,6 +7628,9 @@ + } + #endif + ++#ifdef FEAT_GUI_BEOS ++ vim_unlock_screen(); ++#endif + entered = FALSE; + --RedrawingDisabled; + +@@ -8478,6 +8485,9 @@ + clip_scroll_selection(-line_count); + #endif + ++#ifdef FEAT_GUI_BEOS ++ vim_lock_screen(); ++#endif + #ifdef FEAT_GUI + /* Don't update the GUI cursor here, ScreenLines[] is invalid until the + * scrolling is actually carried out. */ +@@ -8530,6 +8540,10 @@ + } + } + ++#ifdef FEAT_GUI_BEOS ++ vim_unlock_screen(); ++#endif ++ + screen_stop_highlight(); + windgoto(cursor_row, 0); + +@@ -8700,6 +8714,9 @@ + clip_scroll_selection(line_count); + #endif + ++#ifdef FEAT_GUI_BEOS ++ vim_lock_screen(); ++#endif + #ifdef FEAT_GUI + /* Don't update the GUI cursor here, ScreenLines[] is invalid until the + * scrolling is actually carried out. */ +@@ -8759,6 +8776,10 @@ + } + } + ++#ifdef FEAT_GUI_BEOS ++ vim_unlock_screen(); ++#endif ++ + screen_stop_highlight(); + + #ifdef FEAT_VERTSPLIT +diff -Naur vim72/src/structs.h vim72.haiku/src/structs.h +--- vim72/src/structs.h 2009-04-19 20:53:34.000000000 +0000 ++++ vim72.haiku/src/structs.h 2009-04-18 09:16:47.000000000 +0000 +@@ -2239,6 +2239,10 @@ + HMENU submenu_id; /* If this is submenu, add children here */ + HWND tearoff_handle; /* hWnd of tearoff if created */ + #endif ++#if FEAT_GUI_BEOS ++ BMenuItem *id; /* Id of menu item */ ++ BMenu *submenu_id; /* If this is submenu, add children here */ ++#endif + #ifdef FEAT_GUI_MAC + /* MenuHandle id; */ + /* short index; */ /* the item index within the father menu */ +diff -Naur vim72/src/term.c vim72.haiku/src/term.c +--- vim72/src/term.c 2009-04-19 20:53:35.000000000 +0000 ++++ vim72.haiku/src/term.c 2009-04-23 22:45:55.000000000 +0000 +@@ -1436,6 +1436,11 @@ + # define DEFAULT_TERM (char_u *)"beos-ansi" + #endif + ++#ifdef __HAIKU__ ++# undef DEFAULT_TERM ++# define DEFAULT_TERM (char_u *)"xterm" ++#endif ++ + #ifndef DEFAULT_TERM + # define DEFAULT_TERM (char_u *)"dumb" + #endif +diff -Naur vim72/src/ui.c vim72.haiku/src/ui.c +--- vim72/src/ui.c 2009-04-19 20:53:35.000000000 +0000 ++++ vim72.haiku/src/ui.c 2009-04-18 09:16:55.000000000 +0000 +@@ -269,7 +269,7 @@ + mch_suspend(); + } + +-#if !defined(UNIX) || !defined(SIGTSTP) || defined(PROTO) || defined(__BEOS__) ++#if !defined(UNIX) || !defined(SIGTSTP) || defined(PROTO) || defined(__BEOS__) || defined(__HAIKU__) + /* + * When the OS can't really suspend, call this function to start a shell. + * This is never called in the GUI. +@@ -1739,7 +1739,7 @@ + * If we can't get any, and there isn't any in the buffer, we give up and + * exit Vim. + */ +-# ifdef __BEOS__ ++# if defined(__BEOS__) || defined(__HAIKU__) + /* + * On the BeBox version (for now), all input is secretly performed within + * beos_select() which is called from RealWaitForChar(). +diff -Naur vim72/src/version.c vim72.haiku/src/version.c +--- vim72/src/version.c 2009-04-19 20:53:35.000000000 +0000 ++++ vim72.haiku/src/version.c 2009-04-23 22:39:10.000000000 +0000 +@@ -893,6 +893,9 @@ + MSG_PUTS(_("with X11-Athena GUI.")); + # endif + # else ++# ifdef FEAT_GUI_BEOS ++ MSG_PUTS(_("with BeOS/Haiku GUI.")); ++# else + # ifdef FEAT_GUI_PHOTON + MSG_PUTS(_("with Photon GUI.")); + # else +@@ -910,6 +913,7 @@ + # endif + # endif + # endif ++# endif + # endif + # endif + # endif +diff -Naur vim72/src/vim.h vim72.haiku/src/vim.h +--- vim72/src/vim.h 2009-04-19 20:53:35.000000000 +0000 ++++ vim72.haiku/src/vim.h 2009-04-23 22:01:06.000000000 +0000 +@@ -95,6 +95,7 @@ + || defined(FEAT_GUI_MAC) \ + || defined(FEAT_GUI_W32) \ + || defined(FEAT_GUI_W16) \ ++ || defined(FEAT_GUI_BEOS) \ + || defined(FEAT_GUI_PHOTON) + # if !defined(FEAT_GUI) && !defined(NO_X11_INCLUDES) + # define FEAT_GUI +@@ -235,7 +236,7 @@ + # define __ARGS(x) x + #endif + +-#ifdef __BEOS__ ++#if defined(__BEOS__) || defined(__HAIKU__) + # include "os_beos.h" + # define __ARGS(x) x + #endif +@@ -1383,6 +1384,9 @@ + #define STRCPY(d, s) strcpy((char *)(d), (char *)(s)) + #define STRNCPY(d, s, n) strncpy((char *)(d), (char *)(s), (size_t)(n)) + #define STRCMP(d, s) strcmp((char *)(d), (char *)(s)) ++//extern void syslog(int, const char*,...); ++//#define STRCMP(d, s) (syslog(6, "%s:%d",__FILE__,__LINE__),strcmp((char *)(d), (char *)(s))) ++ + #define STRNCMP(d, s, n) strncmp((char *)(d), (char *)(s), (size_t)(n)) + #ifdef HAVE_STRCASECMP + # define STRICMP(d, s) strcasecmp((char *)(d), (char *)(s)) +@@ -1789,6 +1793,9 @@ + int_u format; /* Vim's own special clipboard format */ + int_u format_raw; /* Vim's raw text clipboard format */ + # endif ++# ifdef FEAT_GUI_BEOS ++ /* no clipboard at the moment */ ++# endif + } VimClipboard; + #else + typedef int VimClipboard; /* This is required for the prototypes. */ diff --git a/app-editors/vim/vim-7.2.bep b/app-editors/vim/vim-7.2.bep new file mode 100644 index 000000000..815818832 --- /dev/null +++ b/app-editors/vim/vim-7.2.bep @@ -0,0 +1,24 @@ +DESCRIPTION="Vim is highly configurable text editor." +HOMEPAGE="http://www.vim.org" +SRC_URI="ftp://ftp.vim.org/pub/vim/extra/vim-7.2-extra.tar.gz + ftp://ftp.vim.org/pub/vim/extra/vim-7.2-lang.tar.gz + ftp://ftp.vim.org/pub/vim/unix/vim-7.2.tar.bz2 " +#SRC_URI="http://zzbsd.zz-nest/vim-7.2.tar.gz" +REVISION="1" +STATUS_R5="untested" +STATUS_BONE="untested" +STATUS_HAIKU="unstable" +DEPEND="" +BUILD { + cd vim72 + cd src + autoconf -o auto/configure configure.in + cd ../ + ./configure --prefix=/boot/common --with-features=big + make +} + +INSTALL { + cd vim72/src + make install_beos +}