From cda616008fad191d8797ecd8f4cb4607fb5bff10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emir=20Sar=C4=B1?= Date: Mon, 27 Apr 2020 11:44:53 +0000 Subject: [PATCH] Vim: bump version (#4900) * upstream patchset --- app-editors/vim/patches/vim-8.1.1240.patchset | 7289 ----------------- ...im-8.1.1240.recipe => vim-8.2.0647.recipe} | 108 +- 2 files changed, 53 insertions(+), 7344 deletions(-) delete mode 100644 app-editors/vim/patches/vim-8.1.1240.patchset rename app-editors/vim/{vim-8.1.1240.recipe => vim-8.2.0647.recipe} (56%) diff --git a/app-editors/vim/patches/vim-8.1.1240.patchset b/app-editors/vim/patches/vim-8.1.1240.patchset deleted file mode 100644 index 001457fb4..000000000 --- a/app-editors/vim/patches/vim-8.1.1240.patchset +++ /dev/null @@ -1,7289 +0,0 @@ -From 6e70e49e9489665ebea93db659cb7f02bef5ce4d Mon Sep 17 00:00:00 2001 -From: Adrien Destugues -Date: Wed, 1 May 2019 09:51:42 +0200 -Subject: Import 8.0 patch: new files. - - -diff --git a/runtime/doc/os_haiku.txt b/runtime/doc/os_haiku.txt -new file mode 100644 -index 0000000..ebcb247 ---- /dev/null -+++ b/runtime/doc/os_haiku.txt -@@ -0,0 +1,223 @@ -+*os_haiku.txt* For Vim version 7.4. Last change: 2013 Sep 12 -+ -+ -+ VIM REFERENCE MANUAL by Bram Moolenaar -+ -+ *Haiku* -+ -+This file contains the particularities for the Haiku version of Vim. For -+matters not discussed in this file, Vim behaves very much like the Unix -+|os_unix.txt| version. -+ -+ 1. General |haiku-general| -+ 2. Compiling Vim |haiku-compiling| -+ 3. The Haiku GUI |haiku-gui| -+ 4. The $VIM directory |haiku-vimdir| -+ 5. The $BE_USER_SETTINGS -+ directory |haiku-user-settings-dir| -+ 6. Drag & Drop |haiku-dragndrop| -+ 7. Single Launch vs. Multiple -+ Launch |haiku-launch| -+ 8. Fonts |haiku-fonts| -+ 9. The meta key modifier |haiku-meta| -+10. Mouse key mappings |haiku-mouse| -+11. Color names |haiku-colors| -+12. Credits |haiku-support-credits| -+13. Bugs & things To Do |haiku-bugs| -+ -+ -+1. General *haiku-general* -+ -+The default syntax highlighting mostly works with different foreground colors -+to highlight items. This works best if you set your Terminal window to a -+darkish background and light letters. Some middle-grey background (for -+instance (r,g,b)=(168,168,168)) with black letters also works nicely. -+ -+ -+2. Compiling Vim *haiku-compiling* -+ -+Vim can be compiled using the standard configure/make approach. Running -+./configure without any arguments or passing --enable-gui=haiku, will compile -+vim with the Haiku GUI support. Run ./configure --help , to find out other -+features you can enable/disable. -+ -+Now you should use "make" to compile Vim, then "make install" to install it. -+For seamless integration into the Haiku the GUI-less vim binary should be -+additionally installed over the GUI version. Typical build commands are: > -+ -+ ./configure --prefix=`finddir B_COMMON_DIRECTORY` \ -+ --datarootdir=`finddir B_COMMON_DATA_DIRECTORY` \ -+ --mandir=`finddir B_COMMON_DOCUMENTATION_DIRECTORY`/man \ -+ make clean -+ make install -+ -+ ./configure --prefix=`finddir B_COMMON_DIRECTORY` \ -+ --datarootdir=`finddir B_COMMON_DATA_DIRECTORY` \ -+ --mandir=`finddir B_COMMON_DOCUMENTATION_DIRECTORY`/man \ -+ --disable-gui -+ make clean -+ make install -+ -+ -+3. The Haiku GUI *haiku-gui* -+ -+Normally Vim starts with the GUI if you start it as gvim or vim -g. The vim -+version with GUI tries to determine if it was started from the Tracker instead -+of the Terminal, and if so, use the GUI anyway. However, the current detection -+scheme is fooled if you use the command "vim - -+ -+ :version -+ -+The normal value is /boot/common/data/vim. If you don't like it you can -+set the VIM environment variable to override this, or set 'helpfile' in your -+.vimrc: > -+ -+ :if version >= 500 -+ : set helpfile=~/vim/vim74/doc/help.txt -+ : syntax on -+ :endif -+ -+ -+5. The $USER_SETTINGS_DIR directory *haiku-user-settings-dir* -+ -+$USER_SETTINGS_DIR is the symbolic name for the place where Haiku -+configuration and settings files are stored. -+ -+The normal value is /boot/home/config/settings. -+ -+ -+6. Drag & Drop *haiku-dragndrop* -+ -+You can drop files and directories on either the Vim icon (starts a new Vim -+session, unless you use the File Types application to set Vim to be "Single -+Launch") or on the Vim window (starts editing the files). Dropping a folder -+sets Vim's current working directory. |:cd| |:pwd| If you drop files or -+folders with either SHIFT key pressed, Vim changes directory to the folder -+that contains the first item dropped. When starting Vim, there is no need to -+press shift: Vim behaves as if you do. -+ -+Files dropped set the current argument list. |argument-list| -+ -+ -+7. Single Launch vs. Multiple Launch *haiku-launch* -+ -+As distributed Vim's Application Flags (as seen in the FileTypes preference) -+are set to Multiple Launch. If you prefer, you can set them to Single Launch -+instead. Attempts to start a second copy of Vim will cause the first Vim to -+open the files instead. This works from the Tracker but also from the command -+line. In the latter case, non-file (option) arguments are not supported. -+Another drawback of the Single Launch is silent ignore of "Open With ..." -+requests by vim instance that running as non-GUI application even GUI support -+was compiled in. Vim instance running with GUI has no such problems. -+ -+NB: Only the GUI version has a BApplication (and hence Application Flags). -+This section does not apply to the GUI-less version, should you compile one. -+ -+ -+8. Fonts *haiku-fonts* -+ -+Set fonts with > -+ -+ :set guifont=DejaVu_Sans_Mono/Book/12 -+ -+where the first part is the font family, the second part the style, and the -+third part the size. You can use underscores instead of spaces in family and -+style. -+ -+Best results are obtained with monospaced fonts. Vim attempts to use all -+fonts in B_FIXED_SPACING mode but apparently this does not work for -+proportional fonts (despite what the BeBook says). -+ -+To verify which encodings are supported by the current font give the > -+ -+ :digraphs -+ -+command, which lists a bunch of characters with their ISO Latin 1 encoding. -+If, for instance, there are "box" characters among them, or the last character -+isn't a dotted-y, then for this font the encoding does not work. -+ -+If the font you specify is unavailable, you get the system fixed font. -+ -+GUI Font Selection Dialog is available at giving the > -+ -+ :set guifont=* -+ -+command. -+ -+ -+9. The meta key modifier *haiku-meta* -+ -+The META key modifier is obtained by the left or right OPTION keys. This is -+because the ALT (aka COMMAND) keys are not passed to applications. -+ -+ -+10. Mouse key mappings *haiku-mouse* -+ -+Vim calls the various mouse buttons LeftMouse, MiddleMouse and RightMouse. If -+you use the default Mouse preference settings these names indeed correspond to -+reality. Vim uses this mapping: -+ -+ Button 1 -> LeftMouse, -+ Button 2 -> RightMouse, -+ Button 3 -> MiddleMouse. -+ -+If your mouse has fewer than 3 buttons you can provide your own mapping from -+mouse clicks with modifier(s) to other mouse buttons. See the file -+$VIM/macros/swapmous.vim for an example. |gui-mouse-mapping| -+ -+ -+11. Color names *haiku-colors* -+ -+Vim has a number of color names built-in. Additional names are read from the -+file $VIMRUNTIME/rgb.txt, if present. This file is basically the color -+database from X. Names used from this file are cached for efficiency. -+ -+ -+12. GUI Toolbar Images *haiku-toolbar-images* -+ -+Alternative set of toolbar images should be the PNG image of any height you -+like. Image width is calculated to contain at least 32 buttons in one-row -+cells. -+The image should be stored under the name $VIRUNTIME/bitmaps/builtin-tools.png -+More info about the buttons assignment are at |builtin-tools|. -+ -+ -+13. Credits *haiku-support-credits* -+ -+Haiku port is based on work done for BeOS version by many people -+ - BeBox GUI support Copyright 1998 by Olaf Seibert; -+ - Ported to R4 by Richard Offer Jul 99; -+ - Those who contributed, not listed above but not forgotten; -+ - Haiku support by Siarzhuk Zharski Apr-Mai 2009. -+ -+Thank you, all! -+ -+ -+13. Bugs & things To Do *haiku-bugs* -+ -+The port is under development now and far away from the perfect state. Bug -+reports, patches and wishes are welcome. -+ -+ -+ -Siarzhuk Zharski -+ -+ -+ vim:tw=78:ts=8:ft=help:norl: -diff --git a/runtime/lang/menu_pl.utf-8.vim b/runtime/lang/menu_pl.utf-8.vim -new file mode 100644 -index 0000000..a746df2 ---- /dev/null -+++ b/runtime/lang/menu_pl.utf-8.vim -@@ -0,0 +1,3 @@ -+" Menu Translations: Polish -+ -+source :p:h/menu_pl_pl.utf-8.vim -diff --git a/src/gui_haiku.cc b/src/gui_haiku.cc -new file mode 100644 -index 0000000..ef0ec7d ---- /dev/null -+++ b/src/gui_haiku.cc -@@ -0,0 +1,5292 @@ -+/* 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. -+ * -+ * Based on "GUI support for the Buzzword Enhanced Operating System." -+ * -+ * Ported to R4 by Richard Offer Jul 99 -+ * -+ * Haiku support by Siarzhuk Zharski Apr-Mai 2009 -+ * -+ */ -+ -+/* -+ * Structure of the Haiku 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 -+ -+#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 -+#include -+//#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+class VimApp; -+class VimFormView; -+class VimTextAreaView; -+class VimWindow; -+class VimToolbar; -+class VimTabLine; -+ -+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* fFilePanel; -+ 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; -+ -+#ifdef FEAT_TOOLBAR -+ public: -+ float ToolbarHeight() const; -+ VimToolbar *ToolBar() const -+ { return toolBar; } -+ private: -+ VimToolbar *toolBar; -+#endif -+ -+#ifdef FEAT_GUI_TABLINE -+ public: -+ VimTabLine *TabLine() const { return tabLine; } -+ bool IsShowingTabLine() const { return showingTabLine; } -+ void SetShowingTabLine(bool showing) { showingTabLine = showing; } -+ float TablineHeight() const; -+ private: -+ VimTabLine *tabLine; -+ int showingTabLine; -+#endif -+}; -+ -+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; -+}; -+ -+ -+#ifdef FEAT_TOOLBAR -+ -+class VimToolbar : public BBox -+{ -+ static BBitmap *normalButtonsBitmap; -+ static BBitmap *grayedButtonsBitmap; -+ -+ BBitmap *LoadVimBitmap(const char* fileName); -+ bool GetPictureFromBitmap(BPicture *pictureTo, int32 index, BBitmap *bitmapFrom, bool pressed); -+ bool ModifyBitmapToGrayed(BBitmap *bitmap); -+ -+ BList fButtonsList; -+ void InvalidateLayout(); -+ -+ public: -+ VimToolbar(BRect frame, const char * name); -+ ~VimToolbar(); -+ -+ bool PrepareButtonBitmaps(); -+ -+ bool AddButton(int32 index, vimmenu_T *menu); -+ bool RemoveButton(vimmenu_T *menu); -+ bool GrayButton(vimmenu_T *menu, int grey); -+ -+ float ToolbarHeight() const; -+ virtual void AttachedToWindow(); -+}; -+ -+BBitmap *VimToolbar::normalButtonsBitmap = NULL; -+BBitmap *VimToolbar::grayedButtonsBitmap = NULL; -+ -+const float ToolbarMargin = 3.; -+const float ButtonMargin = 3.; -+ -+#endif /*FEAT_TOOLBAR*/ -+ -+#ifdef FEAT_GUI_TABLINE -+ -+class VimTabLine : public BTabView -+{ -+ public: -+ class VimTab : public BTab { -+ public: -+ VimTab() : BTab(new BView(BRect(), "-Empty-", 0, 0)) {} -+ -+ virtual void Select(BView* owner); -+ }; -+ -+ VimTabLine(BRect r) : BTabView(r, "vimTabLine", B_WIDTH_FROM_LABEL, -+ B_FOLLOW_LEFT | B_FOLLOW_TOP | B_FOLLOW_RIGHT, B_WILL_DRAW | B_FRAME_EVENTS) {} -+ -+ float TablineHeight() const; -+ virtual void MouseDown(BPoint point); -+}; -+ -+#endif //FEAT_GUI_TABLINE -+ -+ -+/* -+ * 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: -+ -+ class View : public BView { -+ typedef BView Inherited; -+ -+ public: -+ View(BRect frame); -+ ~View(); -+ -+ virtual void Draw(BRect updateRect); -+ void InitIcon(int32 type); -+ -+ private: -+ BBitmap* fIconBitmap; -+ }; -+ -+ VimDialog(int type, const char *title, const char *message, -+ const char *buttons, int dfltbutton, const char *textfield, -+ int ex_cmd); -+ ~VimDialog(); -+ -+ int Go(); -+ -+ virtual void MessageReceived(BMessage *msg); -+ -+ private: -+ sem_id fDialogSem; -+ int fDialogValue; -+ BList fButtonsList; -+ BTextView* fMessageView; -+ BTextControl* fInputControl; -+ const char* fInputValue; -+}; -+ -+class VimSelectFontDialog : public BWindow -+{ -+ typedef BWindow Inherited; -+ -+ void _CleanList(BListView* list); -+ void _UpdateFontStyles(); -+ void _UpdateSizeInputPreview(); -+ void _UpdateFontPreview(); -+ bool _UpdateFromListItem(BListView* list, char* text, int textSize); -+ public: -+ -+ VimSelectFontDialog(font_family* family, font_style* style, float* size); -+ ~VimSelectFontDialog(); -+ -+ bool Go(); -+ -+ virtual void MessageReceived(BMessage *msg); -+ -+ private: -+ status_t fStatus; -+ sem_id fDialogSem; -+ bool fDialogValue; -+ font_family* fFamily; -+ font_style* fStyle; -+ float* fSize; -+ font_family fFontFamily; -+ font_style fFontStyle; -+ float fFontSize; -+ BStringView* fPreview; -+ BListView* fFamiliesList; -+ BListView* fStylesList; -+ BListView* fSizesList; -+ BTextControl* fSizesInput; -+}; -+ -+#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 VimTablineMsg { -+ int index; -+}; -+ -+struct VimTablineMenuMsg { -+ int index; -+ int event; -+}; -+ -+struct VimMsg { -+ enum VimMsgType { -+ Key, Resize, ScrollBar, Menu, Mouse, MouseMoved, Focus, Refs, Tabline, TablineMenu -+ }; -+ -+ 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; -+ struct VimTablineMsg Tabline; -+ struct VimTablineMenuMsg TablineMenu; -+ } 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((char *)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), -+ fFilePanel(NULL) -+{ -+} -+ -+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 == fFilePanel) -+ { -+ 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), -+#ifdef FEAT_TOOLBAR -+ toolBar(NULL), -+#endif -+#ifdef FEAT_GUI_TABLINE -+// showingTabLine(false), -+ tabLine(NULL), -+#endif -+ 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 -+ } -+ -+#ifdef FEAT_TOOLBAR -+ delete toolBar; -+#endif -+ -+#ifdef FEAT_GUI_TABLINE -+ delete tabLine; -+#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); -+ -+#ifdef FEAT_TOOLBAR -+ toolBar = new VimToolbar(BRect(0,0,0,0), "VimToolBar"); -+ toolBar->PrepareButtonBitmaps(); -+ AddChild(toolBar); -+#endif -+ -+#ifdef FEAT_GUI_TABLINE -+ tabLine = new VimTabLine(BRect(0,0,0,0)); -+// tabLine->PrepareButtonBitmaps(); -+ AddChild(tabLine); -+#endif -+ -+ BRect remaining = frame; -+ textArea = new VimTextAreaView(remaining); -+ AddChild(textArea); -+ /* The textArea will be resized later when menus are added */ -+ -+ gui.vimForm = this; -+} -+ -+#ifdef FEAT_TOOLBAR -+ float -+VimFormView::ToolbarHeight() const -+{ -+ return toolBar ? toolBar->ToolbarHeight() : 0.; -+} -+#endif -+ -+#ifdef FEAT_GUI_TABLINE -+ float -+VimFormView::TablineHeight() const -+{ -+ return (tabLine && IsShowingTabLine()) ? tabLine->TablineHeight() : 0.; -+} -+#endif -+ -+ 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(); -+ -+#ifdef FEAT_MENU -+ remaining.top += MenuHeight(); -+ menuBar->ResizeTo(remaining.right, remaining.top); -+ gui.menu_height = (int) MenuHeight(); -+#endif -+ -+#ifdef FEAT_TOOLBAR -+ toolBar->MoveTo(remaining.left, remaining.top); -+ toolBar->ResizeTo(remaining.right, ToolbarHeight()); -+ remaining.top += ToolbarHeight(); -+ gui.toolbar_height = ToolbarHeight(); -+#endif -+ -+#ifdef FEAT_GUI_TABLINE -+ tabLine->MoveTo(remaining.left, remaining.top); -+ tabLine->ResizeTo(remaining.right + 1, TablineHeight()); -+ remaining.top += TablineHeight(); -+ gui.tabline_height = TablineHeight(); -+#endif -+ -+ textArea->ResizeTo(remaining.Width(), remaining.Height()); -+ textArea->MoveTo(remaining.left, remaining.top); -+ } -+ -+ -+ 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, 1); -+ if(newFont != NOFONT) { -+ gui.norm_font = (GuiFont)newFont; -+ gui_mch_set_font((GuiFont)newFont); -+ if (name && STRCMP(name, "*") != 0) -+ 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, curwin->w_width, 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 curwin->w_width) -+ { -+ 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, int ex_cmd) -+: 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 -+ VimDialog::View* view = new VimDialog::View(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.SetByteAt(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; -+} -+ -+VimDialog::View::View(BRect frame) -+ : BView(frame, "VimDialogView", B_FOLLOW_ALL_SIDES, B_WILL_DRAW), -+ fIconBitmap(NULL) -+{ -+ SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); -+} -+ -+VimDialog::View::~View() -+{ -+ delete fIconBitmap; -+} -+ -+void VimDialog::View::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 VimDialog::View::InitIcon(int32 type) -+{ -+ if(type == VIM_GENERIC) -+ return; -+ -+ 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(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; -+ } -+ -+ const 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; -+ // 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) -+ return; -+ -+ // 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(fIconBitmap->ColorSpace() != B_CMAP8) -+ BIconUtils::ConvertFromCMAP8(iconData, iconSize, iconSize, iconSize, fIconBitmap); -+} -+ -+const unsigned int kVimDialogOKButtonMsg = 'FDOK'; -+const unsigned int kVimDialogCancelButtonMsg = 'FDCN'; -+const unsigned int kVimDialogSizeInputMsg = 'SICH'; -+const unsigned int kVimDialogFamilySelectMsg = 'MSFM'; -+const unsigned int kVimDialogStyleSelectMsg = 'MSST'; -+const unsigned int kVimDialogSizeSelectMsg = 'MSSZ'; -+ -+VimSelectFontDialog::VimSelectFontDialog(font_family* family, font_style* style, float* size) -+: BWindow(kDefaultRect, "Font Selection", B_TITLED_WINDOW_LOOK, B_MODAL_APP_WINDOW_FEEL, -+ B_NOT_CLOSABLE | B_NOT_RESIZABLE | -+ B_NOT_ZOOMABLE | B_NOT_MINIMIZABLE | B_ASYNCHRONOUS_CONTROLS) -+ , fStatus(B_NO_INIT) -+ , fDialogSem(-1) -+ , fDialogValue(false) -+ , fFamily(family) -+ , fStyle(style) -+ , fSize(size) -+ , fFontSize(*size) -+ , fPreview(0) -+ , fFamiliesList(0) -+ , fStylesList(0) -+ , fSizesList(0) -+ , fSizesInput(0) -+{ -+ strncpy(fFontFamily, *family, B_FONT_FAMILY_LENGTH); -+ strncpy(fFontStyle, *style, B_FONT_STYLE_LENGTH); -+ -+ // "client" area view -+ BBox *clientBox = new BBox(Bounds(), B_EMPTY_STRING, B_FOLLOW_ALL_SIDES, -+ B_WILL_DRAW | B_FRAME_EVENTS | B_NAVIGABLE_JUMP | B_PULSE_NEEDED, -+ B_PLAIN_BORDER); -+ AddChild(clientBox); -+ -+ // client view -+ BRect RC = clientBox->Bounds(); -+ RC.InsetBy(kVimDialogSpacingX, kVimDialogSpacingY); -+ BRect rc(RC.LeftTop(), RC.LeftTop()); -+ -+ // at first create all controls -+ fPreview = new BStringView(rc, "preview", "DejaVu Sans Mono"); -+ clientBox->AddChild(fPreview); -+ -+ BBox* boxDivider = new BBox(rc, B_EMPTY_STRING, -+ B_FOLLOW_NONE, B_WILL_DRAW, B_FANCY_BORDER); -+ clientBox->AddChild(boxDivider); -+ -+ BStringView *labelFamily = new BStringView(rc, "labelFamily", "Family:"); -+ clientBox->AddChild(labelFamily); -+ labelFamily->ResizeToPreferred(); -+ -+ BStringView *labelStyle = new BStringView(rc, "labelStyle", "Style:"); -+ clientBox->AddChild(labelStyle); -+ labelStyle->ResizeToPreferred(); -+ -+ BStringView *labelSize = new BStringView(rc, "labelSize", "Size:"); -+ clientBox->AddChild(labelSize); -+ labelSize->ResizeToPreferred(); -+ -+ fFamiliesList = new BListView(rc, "listFamily", -+ B_SINGLE_SELECTION_LIST, B_FOLLOW_ALL_SIDES); -+ BScrollView *scrollFamilies = new BScrollView("scrollFamily", -+ fFamiliesList, B_FOLLOW_LEFT_RIGHT, 0, false, true); -+ clientBox->AddChild(scrollFamilies); -+ -+ fStylesList= new BListView(rc, "listStyles", -+ B_SINGLE_SELECTION_LIST, B_FOLLOW_ALL_SIDES); -+ BScrollView *scrollStyles = new BScrollView("scrollStyle", -+ fStylesList, B_FOLLOW_LEFT_RIGHT, 0, false, true); -+ clientBox->AddChild(scrollStyles); -+ -+ fSizesInput = new BTextControl(rc, "inputSize", NULL, "???", -+ new BMessage(kVimDialogSizeInputMsg)); -+ clientBox->AddChild(fSizesInput); -+ fSizesInput->ResizeToPreferred(); -+ -+ fSizesList = new BListView(rc, "listSizes", -+ B_SINGLE_SELECTION_LIST, B_FOLLOW_ALL_SIDES); -+ BScrollView *scrollSizes = new BScrollView("scrollSize", -+ fSizesList, B_FOLLOW_LEFT_RIGHT, 0, false, true); -+ clientBox->AddChild(scrollSizes); -+ -+ BButton *buttonOK = new BButton(rc, "buttonOK", "OK", -+ new BMessage(kVimDialogOKButtonMsg)); -+ clientBox->AddChild(buttonOK); -+ buttonOK->ResizeToPreferred(); -+ -+ BButton *buttonCancel = new BButton(rc, "buttonCancel", "Cancel", -+ new BMessage(kVimDialogCancelButtonMsg)); -+ clientBox->AddChild(buttonCancel); -+ buttonCancel->ResizeToPreferred(); -+ -+ // layout controls -+ float lineHeight = labelFamily->Bounds().Height(); -+ float previewHeight = lineHeight * 3; -+ float offsetYLabels = previewHeight + kVimDialogSpacingY; -+ float offsetYLists = offsetYLabels + lineHeight + kVimDialogSpacingY / 2; -+ float offsetYSizes = offsetYLists + fSizesInput->Bounds().Height() + kVimDialogSpacingY / 2; -+ float listsHeight = lineHeight * 9; -+ float offsetYButtons = offsetYLists + listsHeight + kVimDialogSpacingY; -+ float maxControlsHeight = offsetYButtons + buttonOK->Bounds().Height(); -+ float familiesWidth = labelFamily->Bounds().Width() * 5; -+ float offsetXStyles = familiesWidth + kVimDialogSpacingX; -+ float stylesWidth = labelStyle->Bounds().Width() * 4; -+ float offsetXSizes = offsetXStyles + stylesWidth + kVimDialogSpacingX; -+ float sizesWidth = labelSize->Bounds().Width() * 2; -+ float maxControlsWidth = offsetXSizes + sizesWidth; -+ -+ ResizeTo(maxControlsWidth + kVimDialogSpacingX * 2, -+ maxControlsHeight + kVimDialogSpacingY * 2); -+ -+ BRect rcVim = gui.vimWindow->Frame(); -+ MoveTo(rcVim.left + (rcVim.Width() - Frame().Width()) / 2, -+ rcVim.top + (rcVim.Height() - Frame().Height()) / 2); -+ -+ fPreview->ResizeTo(maxControlsWidth, previewHeight); -+ fPreview->SetAlignment(B_ALIGN_CENTER); -+ -+ boxDivider->MoveBy(0.f, previewHeight + kVimDialogSpacingY / 2); -+ boxDivider->ResizeTo(maxControlsWidth, 1.f); -+ -+ labelFamily->MoveBy(0.f, offsetYLabels); -+ labelStyle->MoveBy(offsetXStyles, offsetYLabels); -+ labelSize->MoveBy(offsetXSizes, offsetYLabels); -+ -+ // text control alignment issues -+ float insetX = fSizesInput->TextView()->Bounds().Width() - fSizesInput->Bounds().Width(); -+ float insetY = fSizesInput->TextView()->Bounds().Width() - fSizesInput->Bounds().Width(); -+ -+ scrollFamilies->MoveBy(0.f, offsetYLists); -+ scrollStyles->MoveBy(offsetXStyles, offsetYLists); -+ fSizesInput->MoveBy(offsetXSizes + insetX / 2, offsetYLists + insetY / 2); -+ scrollSizes->MoveBy(offsetXSizes, offsetYSizes); -+ -+ fSizesInput->SetAlignment(B_ALIGN_CENTER, B_ALIGN_CENTER); -+ -+ scrollFamilies->ResizeTo(familiesWidth, listsHeight); -+ scrollStyles->ResizeTo(stylesWidth, listsHeight); -+ fSizesInput->ResizeTo(sizesWidth, fSizesInput->Bounds().Height()); -+ scrollSizes->ResizeTo(sizesWidth, -+ listsHeight - (offsetYSizes - offsetYLists)); -+ -+ buttonOK->MoveBy(maxControlsWidth - buttonOK->Bounds().Width(), offsetYButtons); -+ buttonCancel->MoveBy(maxControlsWidth - buttonOK->Bounds().Width() -+ - buttonCancel->Bounds().Width() - kVimDialogSpacingX, offsetYButtons); -+ -+ // fill lists -+ int selIndex = -1; -+ int count = count_font_families(); -+ for (int i = 0; i < count; i++) { -+ font_family family; -+ if (get_font_family(i, &family ) == B_OK) { -+ fFamiliesList->AddItem(new BStringItem((const char*)family)); -+ if (strncmp(family, fFontFamily, B_FONT_FAMILY_LENGTH) == 0) -+ selIndex = i; -+ } -+ } -+ -+ if (selIndex >= 0) { -+ fFamiliesList->Select(selIndex); -+ fFamiliesList->ScrollToSelection(); -+ } -+ -+ _UpdateFontStyles(); -+ -+ selIndex = -1; -+ for (int size = 8, index = 0; size <= 18; size++, index++) { -+ BString str; -+ str << size; -+ fSizesList->AddItem(new BStringItem(str)); -+ if (size == fFontSize) -+ selIndex = index; -+ -+ } -+ -+ if (selIndex >= 0) { -+ fSizesList->Select(selIndex); -+ fSizesList->ScrollToSelection(); -+ } -+ -+ fFamiliesList->SetSelectionMessage(new BMessage(kVimDialogFamilySelectMsg)); -+ fStylesList->SetSelectionMessage(new BMessage(kVimDialogStyleSelectMsg)); -+ fSizesList->SetSelectionMessage(new BMessage(kVimDialogSizeSelectMsg)); -+ fSizesInput->SetModificationMessage(new BMessage(kVimDialogSizeInputMsg)); -+ -+ _UpdateSizeInputPreview(); -+ _UpdateFontPreview(); -+ -+ fStatus = B_OK; -+} -+ -+VimSelectFontDialog::~VimSelectFontDialog() -+{ -+ _CleanList(fFamiliesList); -+ _CleanList(fStylesList); -+ _CleanList(fSizesList); -+ -+ if (fDialogSem > B_OK) -+ delete_sem(fDialogSem); -+} -+ -+ void -+VimSelectFontDialog::_CleanList(BListView* list) -+{ -+ while(0 < list->CountItems()) -+ delete (dynamic_cast(list->RemoveItem((int32)0))); -+} -+ -+ bool -+VimSelectFontDialog::Go() -+{ -+ if (fStatus != B_OK) { -+ Quit(); -+ return NOFONT; -+ } -+ -+ fDialogSem = create_sem(0, "VimFontSelectDialogSem"); -+ if(fDialogSem < B_OK) { -+ Quit(); -+ return fDialogValue; -+ } -+ -+ Show(); -+ -+ while(acquire_sem(fDialogSem) == B_INTERRUPTED); -+ -+ bool retValue = fDialogValue; -+ -+ if(Lock()) -+ Quit(); -+ -+ return retValue; -+} -+ -+ -+void VimSelectFontDialog::_UpdateFontStyles() -+{ -+ _CleanList(fStylesList); -+ -+ int32 selIndex = -1; -+ int32 count = count_font_styles(fFontFamily); -+ for (int32 i = 0; i < count; i++) { -+ font_style style; -+ uint32 flags = 0; -+ if (get_font_style(fFontFamily, i, &style, &flags) == B_OK) { -+ fStylesList->AddItem(new BStringItem((const char*)style)); -+ if (strncmp(style, fFontStyle, B_FONT_STYLE_LENGTH) == 0) -+ selIndex = i; -+ } -+ } -+ -+ if (selIndex >= 0) { -+ fStylesList->Select(selIndex); -+ fStylesList->ScrollToSelection(); -+ } else -+ fStylesList->Select(0); -+} -+ -+ -+void VimSelectFontDialog::_UpdateSizeInputPreview() -+{ -+ char buf[10] = {0}; -+ vim_snprintf(buf, sizeof(buf), (char*)"%.0f", fFontSize); -+ fSizesInput->SetText(buf); -+} -+ -+ -+void VimSelectFontDialog::_UpdateFontPreview() -+{ -+ BFont font; -+ fPreview->GetFont(&font); -+ font.SetSize(fFontSize); -+ font.SetFamilyAndStyle(fFontFamily, fFontStyle); -+ fPreview->SetFont(&font, B_FONT_FAMILY_AND_STYLE | B_FONT_SIZE); -+ -+ BString str; -+ str << fFontFamily << " " << fFontStyle << ", " << (int)fFontSize << " pt."; -+ fPreview->SetText(str); -+} -+ -+ -+ bool -+VimSelectFontDialog::_UpdateFromListItem(BListView* list, char* text, int textSize) -+{ -+ int32 index = list->CurrentSelection(); -+ if (index < 0) -+ return false; -+ BStringItem* item = (BStringItem*)list->ItemAt(index); -+ if (item == NULL) -+ return false; -+ strncpy(text, item->Text(), textSize); -+ return true; -+} -+ -+ -+void VimSelectFontDialog::MessageReceived(BMessage *msg) -+{ -+ switch (msg->what) { -+ case kVimDialogOKButtonMsg: -+ strncpy(*fFamily, fFontFamily, B_FONT_FAMILY_LENGTH); -+ strncpy(*fStyle, fFontStyle, B_FONT_STYLE_LENGTH); -+ *fSize = fFontSize; -+ fDialogValue = true; -+ case kVimDialogCancelButtonMsg: -+ delete_sem(fDialogSem); -+ fDialogSem = -1; -+ return; -+ case B_KEY_UP: -+ { -+ int32 key = 0; -+ if (msg->FindInt32("raw_char", &key) == B_OK -+ && key == B_ESCAPE) { -+ delete_sem(fDialogSem); -+ fDialogSem = -1; -+ } -+ } -+ break; -+ -+ case kVimDialogFamilySelectMsg: -+ if (_UpdateFromListItem(fFamiliesList, -+ fFontFamily, B_FONT_FAMILY_LENGTH)) { -+ _UpdateFontStyles(); -+ _UpdateFontPreview(); -+ } -+ break; -+ case kVimDialogStyleSelectMsg: -+ if (_UpdateFromListItem(fStylesList, -+ fFontStyle, B_FONT_STYLE_LENGTH)) -+ _UpdateFontPreview(); -+ break; -+ case kVimDialogSizeSelectMsg: -+ { -+ char buf[10] = {0}; -+ if (_UpdateFromListItem(fSizesList, buf, sizeof(buf))) { -+ float size = atof(buf); -+ if (size > 0.f) { -+ fFontSize = size; -+ _UpdateSizeInputPreview(); -+ _UpdateFontPreview(); -+ } -+ } -+ } -+ break; -+ case kVimDialogSizeInputMsg: -+ { -+ float size = atof(fSizesInput->Text()); -+ if (size > 0.f) { -+ fFontSize = size; -+ _UpdateFontPreview(); -+ } -+ } -+ break; -+ default: -+ break; -+ } -+ return BWindow::MessageReceived(msg); -+} -+ -+#endif /* FEAT_GUI_DIALOG */ -+ -+#ifdef FEAT_TOOLBAR -+ -+// some forward declaration required by toolbar functions... -+static BMessage * MenuMessage(vimmenu_T *menu); -+ -+VimToolbar::VimToolbar(BRect frame, const char *name) : -+ BBox(frame, name, B_FOLLOW_LEFT | B_FOLLOW_TOP, B_WILL_DRAW | B_FRAME_EVENTS, B_PLAIN_BORDER) -+{ -+} -+ -+VimToolbar::~VimToolbar() -+{ -+ int32 count = fButtonsList.CountItems(); -+ for(int32 i = 0; i < count; i++) -+ delete (BPictureButton*)fButtonsList.ItemAt(i); -+ fButtonsList.MakeEmpty(); -+ -+ delete normalButtonsBitmap; -+ delete grayedButtonsBitmap; -+ normalButtonsBitmap = NULL; -+ grayedButtonsBitmap = NULL; -+} -+ -+ void -+VimToolbar::AttachedToWindow() -+{ -+ BBox::AttachedToWindow(); -+ -+ SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); -+} -+ -+ float -+VimToolbar::ToolbarHeight() const -+{ -+ float size = NULL == normalButtonsBitmap ? 18. : normalButtonsBitmap->Bounds().Height(); -+ return size + ToolbarMargin * 2 + ButtonMargin * 2 + 1; -+} -+ -+ bool -+VimToolbar::ModifyBitmapToGrayed(BBitmap *bitmap) -+{ -+ float height = bitmap->Bounds().Height(); -+ float width = bitmap->Bounds().Width(); -+ -+ rgb_color *bits = (rgb_color*)bitmap->Bits(); -+ int32 pixels = bitmap->BitsLength() / 4; -+ for(int32 i = 0; i < pixels; i++) { -+ bits[i].red = bits[i].green = -+ bits[i].blue = ((uint32)bits[i].red + bits[i].green + bits[i].blue) / 3; -+ bits[i].alpha /= 4; -+ } -+ -+ return true; -+} -+ -+ bool -+VimToolbar::PrepareButtonBitmaps() -+{ -+ // first try to load potentially customized $VIRUNTIME/bitmaps/builtin-tools.png -+ normalButtonsBitmap = LoadVimBitmap("builtin-tools.png"); -+ if(normalButtonsBitmap == NULL) -+ // customized not found? dig application resources for "builtin-tools" one -+ normalButtonsBitmap = BTranslationUtils::GetBitmap(B_PNG_FORMAT, "builtin-tools"); -+ -+ if(normalButtonsBitmap == NULL) -+ return false; -+ -+ BMessage archive; -+ normalButtonsBitmap->Archive(&archive); -+ -+ grayedButtonsBitmap = new BBitmap(&archive); -+ if(grayedButtonsBitmap == NULL) -+ return false; -+ -+ // modify grayed bitmap -+ ModifyBitmapToGrayed(grayedButtonsBitmap); -+ -+ return true; -+} -+ -+BBitmap *VimToolbar::LoadVimBitmap(const char* fileName) -+{ -+ BBitmap *bitmap = NULL; -+ -+ int mustfree = 0; -+ char_u* runtimePath = vim_getenv((char_u*)"VIMRUNTIME", &mustfree); -+ if(runtimePath != NULL && fileName != NULL) { -+ BString strPath((char*)runtimePath); -+ strPath << "/bitmaps/" << fileName; -+ bitmap = BTranslationUtils::GetBitmap(strPath.String()); -+ } -+ -+ if(mustfree) -+ vim_free(runtimePath); -+ -+ return bitmap; -+} -+ -+ bool -+VimToolbar::GetPictureFromBitmap(BPicture *pictureTo, int32 index, BBitmap *bitmapFrom, bool pressed) -+{ -+ float size = bitmapFrom->Bounds().Height() + 1.; -+ -+ BView view(BRect(0, 0, size, size), "", 0, 0); -+ -+ AddChild(&view); -+ view.BeginPicture(pictureTo); -+ -+ view.SetHighColor(ui_color(B_PANEL_BACKGROUND_COLOR)); -+ view.FillRect(view.Bounds()); -+ view.SetDrawingMode(B_OP_OVER); -+ -+ BRect source(0, 0, size - 1, size - 1); -+ BRect destination(source); -+ -+ source.OffsetBy(size * index, 0); -+ destination.OffsetBy(ButtonMargin, ButtonMargin); -+ -+ view.DrawBitmap(bitmapFrom, source, destination); -+ -+ if(pressed) { -+ rgb_color shineColor = ui_color(B_SHINE_COLOR); -+ rgb_color shadowColor = ui_color(B_SHADOW_COLOR); -+ size += ButtonMargin * 2 - 1; -+ view.BeginLineArray(4); -+ view.AddLine(BPoint(0, 0), BPoint(size, 0), shadowColor); -+ view.AddLine(BPoint(size, 0), BPoint(size, size), shineColor); -+ view.AddLine(BPoint(size, size), BPoint(0, size), shineColor); -+ view.AddLine(BPoint(0, size), BPoint(0, 0), shadowColor); -+ view.EndLineArray(); -+ } -+ -+ view.EndPicture(); -+ RemoveChild(&view); -+ -+ return true; -+} -+ -+ bool -+VimToolbar::AddButton(int32 index, vimmenu_T *menu) -+{ -+ BPictureButton *button = NULL; -+ if(!menu_is_separator(menu->name)) { -+ float size = normalButtonsBitmap ? -+ normalButtonsBitmap->Bounds().Height() + 1. + ButtonMargin * 2 : 18.; -+ BRect frame(0, 0, size, size); -+ BPicture pictureOn; -+ BPicture pictureOff; -+ BPicture pictureGray; -+ -+ if(menu->iconfile == NULL && menu->iconidx >= 0 && normalButtonsBitmap) { -+ GetPictureFromBitmap(&pictureOn, menu->iconidx, normalButtonsBitmap, true); -+ GetPictureFromBitmap(&pictureOff, menu->iconidx, normalButtonsBitmap, false); -+ GetPictureFromBitmap(&pictureGray, menu->iconidx, grayedButtonsBitmap, false); -+ } else { -+ -+ char_u buffer[MAXPATHL] = {0}; -+ BBitmap *bitmap = NULL; -+ -+ if(menu->iconfile) { -+ gui_find_iconfile(menu->iconfile, buffer, (char*)"png"); -+ bitmap = BTranslationUtils::GetBitmap((char*)buffer); -+ } -+ -+ if(bitmap == NULL && gui_find_bitmap(menu->name, buffer, (char*)"png") == OK) -+ bitmap = BTranslationUtils::GetBitmap((char*)buffer); -+ -+ if(bitmap == NULL) -+ bitmap = new BBitmap(BRect(0, 0, size, size), B_RGB32); -+ -+ GetPictureFromBitmap(&pictureOn, 0, bitmap, true); -+ GetPictureFromBitmap(&pictureOff, 0, bitmap, false); -+ ModifyBitmapToGrayed(bitmap); -+ GetPictureFromBitmap(&pictureGray, 0, bitmap, false); -+ -+ delete bitmap; -+ } -+ -+ button = new BPictureButton(frame, (char*)menu->name, -+ &pictureOff, &pictureOn, MenuMessage(menu)); -+ -+ button->SetDisabledOn(&pictureGray); -+ button->SetDisabledOff(&pictureGray); -+ -+ button->SetTarget(gui.vimTextArea); -+ -+ AddChild(button); -+ -+ menu->button = button; -+ } -+ -+ bool result = fButtonsList.AddItem(button, index); -+ InvalidateLayout(); -+ return result; -+} -+ -+ bool -+VimToolbar::RemoveButton(vimmenu_T *menu) -+{ -+ if(menu->button) { -+ if(fButtonsList.RemoveItem(menu->button)) { -+ delete menu->button; -+ menu->button = NULL; -+ } -+ } -+} -+ -+ bool -+VimToolbar::GrayButton(vimmenu_T *menu, int grey) -+{ -+ if(menu->button) { -+ int32 index = fButtonsList.IndexOf(menu->button); -+ if(index >= 0) -+ menu->button->SetEnabled(grey ? false : true); -+ } -+} -+ -+ void -+VimToolbar::InvalidateLayout() -+{ -+ int32 offset = ToolbarMargin; -+ int32 count = fButtonsList.CountItems(); -+ for(int32 i = 0; i < count; i++) { -+ BPictureButton *button = (BPictureButton *)fButtonsList.ItemAt(i); -+ if(button) { -+ button->MoveTo(offset, ToolbarMargin); -+ offset += button->Bounds().Width() + ToolbarMargin; -+ } else -+ offset += ToolbarMargin * 3; -+ } -+} -+ -+#endif /*FEAT_TOOLBAR*/ -+ -+#if defined(FEAT_GUI_TABLINE) -+ -+ float -+VimTabLine::TablineHeight() const -+{ -+// float size = NULL == normalButtonsBitmap ? 18. : normalButtonsBitmap->Bounds().Height(); -+// return size + ToolbarMargin * 2 + ButtonMargin * 2 + 1; -+ return TabHeight();// + ToolbarMargin; -+} -+ -+void -+VimTabLine::MouseDown(BPoint point) -+{ -+ if(!gui_mch_showing_tabline()) -+ return; -+ -+ BMessage *m = Window()->CurrentMessage(); -+ assert(m); -+ -+ int32 buttons = 0; -+ m->FindInt32("buttons", &buttons); -+ -+ int32 clicks = 0; -+ m->FindInt32("clicks", &clicks); -+ -+ int index = 0; // 0 means here - no tab found -+ for (int i = 0; i < CountTabs(); i++) { -+ if(TabFrame(i).Contains(point)) { -+ index = i + 1; // indexes are 1-based -+ break; -+ } -+ } -+ -+ int event = -1; -+ -+ if ((buttons & B_PRIMARY_MOUSE_BUTTON) && clicks > 1) -+ // left button double click on - create new tab -+ event = TABLINE_MENU_NEW; -+ -+ else if (buttons & B_TERTIARY_MOUSE_BUTTON) -+ // middle button click - close the pointed tab -+ // or create new one in case empty space -+ event = index > 0 ? TABLINE_MENU_CLOSE : TABLINE_MENU_NEW; -+ -+ else if (buttons & B_SECONDARY_MOUSE_BUTTON) { -+ // right button click - show context menu -+ BPopUpMenu* popUpMenu = new BPopUpMenu("tabLineContextMenu", false, false); -+ popUpMenu->AddItem(new BMenuItem(_("Close tabi R"), new BMessage(TABLINE_MENU_CLOSE))); -+ popUpMenu->AddItem(new BMenuItem(_("New tab T"), new BMessage(TABLINE_MENU_NEW))); -+ popUpMenu->AddItem(new BMenuItem(_("Open tab..."), new BMessage(TABLINE_MENU_OPEN))); -+ -+ ConvertToScreen(&point); -+ BMenuItem* item = popUpMenu->Go(point); -+ if (item != NULL) { -+ event = item->Command(); -+ } -+ -+ delete popUpMenu; -+ -+ } else { -+ // default processing -+ BTabView::MouseDown(point); -+ return; -+ } -+ -+ if (event < 0) -+ return; -+ -+ VimTablineMenuMsg tmm; -+ tmm.index = index; -+ tmm.event = event; -+ write_port(gui.vdcmp, VimMsg::TablineMenu, &tmm, sizeof(tmm)); -+} -+ -+void -+VimTabLine::VimTab::Select(BView* owner) -+{ -+ BTab::Select(owner); -+ -+ VimTabLine *tabLine = gui.vimForm->TabLine(); -+ if(tabLine != NULL) { -+ -+ int32 i = 0; -+ for (; i < tabLine->CountTabs(); i++) -+ if(this == tabLine->TabAt(i)) -+ break; -+ -+// printf("%d:%d:%s\n", i, tabLine->CountTabs(), tabLine->TabAt(i)->Label()); -+ if(i < tabLine->CountTabs()) { -+ VimTablineMsg tm; -+ tm.index = i + 1; -+ write_port(gui.vdcmp, VimMsg::Tabline, &tm, sizeof(tm)); -+ } -+ } -+} -+ -+#endif // defined(FEAT_GUI_TABLINE) -+ -+/* ---------------- ---------------- */ -+ -+// some global variables -+static char appsig[] = "application/x-vnd.Haiku-Vim-8"; -+key_map *keyMap; -+char *keyMapChars; -+int main_exitcode = 127; -+ -+ status_t -+gui_haiku_process_event(bigtime_t timeout) -+{ -+ struct VimMsg vm; -+ int32 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; -+ case VimMsg::Tabline: -+ send_tabline_event(vm.u.Tabline.index); -+ break; -+ case VimMsg::TablineMenu: -+ send_tabline_menu_event(vm.u.TablineMenu.index, vm.u.TablineMenu.event); -+ 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 0 -+ -+#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 - 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(); -+ 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->Frame(); -+ 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); -+ -+/*#ifdef FEAT_GUI_TABLINE -+ if(gui.vimForm->TabLine() != NULL) { -+ gui.vimForm->TabLine()->ResizeTo(w, gui.vimForm->TablineHeight()); -+ } -+#endif //FEAT_GUI_TABLINE*/ -+ -+ 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(); -+ } -+} -+ -+void -+gui_mch_destroy_scrollbar( -+ scrollbar_T *sb) -+{ -+ if (gui.vimWindow->Lock()) { -+ sb->id->RemoveSelf(); -+ delete sb->id; -+ gui.vimWindow->Unlock(); -+ } -+} -+ -+ int -+gui_mch_is_blink_off(void) -+{ -+ return FALSE; -+} -+ -+/* -+ * 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; -+} -+ -+ -+ int -+gui_mch_font_dialog(font_family* family, font_style* style, float* size) -+{ -+#if defined(FEAT_GUI_DIALOG) -+ //gui.vimWindow->Unlock(); -+ VimSelectFontDialog *dialog = new VimSelectFontDialog(family, style, size); -+ return dialog->Go(); -+#else -+ return NOFONT; -+#endif /* FEAT_GUI_DIALOG */ -+} -+ -+ -+GuiFont -+gui_mch_get_font( -+ char_u *name, -+ int giveErrorIfMissing) -+{ -+ 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}; -+ float size = 0.f; -+ -+ if (name == 0 && be_fixed_font == 0) { -+ if(giveErrorIfMissing) -+ EMSG2("(fe0) default font is not defined", name); -+ return NOFONT; -+ } -+ -+ bool useSelectGUI = false; -+ if (name != NULL) -+ if (STRCMP(name, "*") == 0) { -+ useSelectGUI = true; -+ STRNCPY(font_name, hl_get_font_name(), buff_size); -+ } else -+ STRNCPY(font_name, name, buff_size); -+ -+ if (font_name[0] == 0) { -+ be_fixed_font->GetFamilyAndStyle(&family, &style); -+ size = be_fixed_font->Size(); -+ vim_snprintf(font_name, buff_size, -+ (char*)"%s/%s/%.0f", family, style, size); -+ } -+ -+ // replace underscores with spaces -+ char* end = 0; -+ while (end = strchr((char *)font_name, '_')) -+ *end = ' '; -+ -+ // store the name before strtok corrupt the buffer ;-) -+ static char buff[buff_size] = {0}; -+ STRNCPY(buff, font_name, buff_size); -+ STRNCPY(family, strtok(buff, "/\0"), B_FONT_FAMILY_LENGTH); -+ char* style_s = strtok(0, "/\0"); -+ if (style_s != 0) -+ STRNCPY(style, style_s, B_FONT_STYLE_LENGTH); -+ size = atof((style_s != 0) ? strtok(0, "/\0") : "0"); -+ -+ if (useSelectGUI) { -+ if(gui_mch_font_dialog(&family, &style, &size) == NOFONT) -+ return FAIL; -+ // compose for further processing -+ vim_snprintf(font_name, buff_size, -+ (char*)"%s/%s/%.0f", family, style, size); -+ hl_set_font_name((char_u*)font_name); -+ -+ // Set guifont to the name of the selected font. -+ char_u* new_p_guifont = alloc(STRLEN(font_name) + 1); -+ if (new_p_guifont != NULL) { -+ STRCPY(new_p_guifont, font_name); -+ vim_free(p_guifont); -+ p_guifont = new_p_guifont; -+ // Replace spaces in the font name with underscores. -+ for ( ; *new_p_guifont; ++new_p_guifont) -+ if (*new_p_guifont == ' ') -+ *new_p_guifont = '_'; -+ } -+ } -+ -+ VimFont *flp; -+ for (flp = fontList; flp; flp = flp->next) { -+ if (STRCMP(font_name, flp->name) == 0) { -+ flp->refcount++; -+ return (GuiFont)flp; -+ } -+ } -+ -+ VimFont *font = new VimFont(); -+ font->name = vim_strsave((char_u*)font_name); -+ -+ 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; -+} -+ -+/* -+ * Display the saved error message(s). -+ */ -+#ifdef USE_MCH_ERRMSG -+ void -+display_errors(void) -+{ -+ char *p; -+ char_u pError[256]; -+ -+ if (error_ga.ga_data == NULL) -+ return; -+ -+ /* avoid putting up a message box with blanks only */ -+ for (p = (char *)error_ga.ga_data; *p; ++p) -+ if (!isspace(*p)) -+ { -+ if (STRLEN(p) > 255) -+ pError[0] = 255; -+ else -+ pError[0] = STRLEN(p); -+ -+ STRNCPY(&pError[1], p, pError[0]); -+// ParamText(pError, nil, nil, nil); -+// Alert(128, nil); -+ break; -+ /* TODO: handled message longer than 256 chars -+ * use auto-sizeable alert -+ * or dialog with scrollbars (TextEdit zone) -+ */ -+ } -+ ga_clear(&error_ga); -+} -+#endif -+ -+ 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; -+ } -+} -+ -+ void -+gui_mch_mousehide(int hide) -+{ -+ fprintf(stderr, "gui_mch_getmouse"); -+ // TODO -+} -+ -+ 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 -+ { -+ const 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)}, -+ // NOTE: some entries are zero-allocated for NDDYNAMIC_COLORS -+ // in this table! -+ }; -+ -+ 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); -+ -+ //NOTE: see note above in table allocation! We are working here with -+ // dynamically allocated names, not constant ones! -+ vim_free((char*)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_haiku_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_haiku_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_haiku_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; -+ -+ // popup menu - just create it unattached -+ if (menu_is_popup(menu->name) && parent == NULL) { -+ BPopUpMenu* popUpMenu = new BPopUpMenu((const char*)menu->name, false, false); -+ menu->submenu_id = popUpMenu; -+ menu->id = NULL; -+ return; -+ } -+ -+ 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; -+ -+ /* 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()) -+ { -+#ifdef FEAT_TOOLBAR -+ if(menu_is_toolbar(parent->name)) { -+ VimToolbar *toolbar = gui.vimForm->ToolBar(); -+ if(toolbar != NULL) { -+ toolbar->AddButton(idx, menu); -+ } -+ } else -+#endif -+ -+ if (parent->submenu_id != NULL || menu_is_popup(parent->name)) { -+ 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()) -+ { -+#ifdef FEAT_TOOLBAR -+ if(menu->parent && menu_is_toolbar(menu->parent->name)) { -+ VimToolbar *toolbar = gui.vimForm->ToolBar(); -+ if(toolbar != NULL) { -+ toolbar->RemoveButton(menu); -+ } -+ } else -+#endif -+ { -+ 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) -+{ -+#ifdef FEAT_TOOLBAR -+ if(menu->parent && menu_is_toolbar(menu->parent->name)) { -+ if (gui.vimWindow->Lock()) { -+ VimToolbar *toolbar = gui.vimForm->ToolBar(); -+ if(toolbar != NULL) { -+ toolbar->GrayButton(menu, grey); -+ } -+ gui.vimWindow->Unlock(); -+ } -+ } else -+#endif -+ 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 */ -+} -+ -+ void -+gui_mch_show_popupmenu(vimmenu_T *menu) -+{ -+ if (!menu_is_popup(menu->name) || menu->submenu_id == NULL) -+ return; -+ -+ BPopUpMenu* popupMenu = dynamic_cast(menu->submenu_id); -+ if (popupMenu == NULL) -+ return; -+ -+ BPoint point; -+ if(gui.vimWindow->Lock()) { -+ uint32 buttons = 0; -+ gui.vimTextArea->GetMouse(&point, &buttons); -+ gui.vimTextArea->ConvertToScreen(&point); -+ gui.vimWindow->Unlock(); -+ } -+ popupMenu->Go(point, true); -+} -+ -+#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) -+{ -+ gui.vimApp->fFilePanel = new BFilePanel((saving == TRUE) ? B_SAVE_PANEL : B_OPEN_PANEL, -+ NULL, NULL, 0, false, -+ new BMessage((saving == TRUE) ? 'save' : 'open'), NULL, true); -+ -+ gui.vimApp->fBrowsedPath.Unset(); -+ -+ gui.vimApp->fFilePanel->Window()->SetTitle((char*)title); -+ gui.vimApp->fFilePanel->SetPanelDirectory((const char*)initdir); -+ -+ gui.vimApp->fFilePanel->Show(); -+ -+ gui.vimApp->fFilePanelSem = create_sem(0, "FilePanelSem"); -+ -+ while(acquire_sem(gui.vimApp->fFilePanelSem) == B_INTERRUPTED); -+ -+ char_u *fileName = NULL; -+ status_t result = gui.vimApp->fBrowsedPath.InitCheck(); -+ if(result == B_OK) { -+ fileName = 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)); -+ } -+ -+ delete gui.vimApp->fFilePanel; -+ gui.vimApp->fFilePanel = NULL; -+ -+ return fileName; -+} -+#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, -+ int ex_cmd) -+{ -+ VimDialog *dialog = new VimDialog(type, (char*)title, (char*)message, -+ (char*)buttons, dfltbutton, (char*)textfield, ex_cmd); -+ return dialog->Go(); -+} -+ -+#endif /* FEAT_GUI_DIALOG */ -+ -+ -+/* -+ * Return the RGB value of a pixel as long. -+ */ -+ guicolor_T -+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 */ -+} -+ -+#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 -+ -+ void -+gui_mch_show_toolbar(int showit) -+{ -+ VimToolbar *toolbar = gui.vimForm->ToolBar(); -+ gui.toolbar_height = (toolbar && showit) ? toolbar->ToolbarHeight() : 0.; -+} -+ -+ void -+gui_mch_set_toolbar_pos(int x, int y, int w, int h) -+{ -+ VimToolbar *toolbar = gui.vimForm->ToolBar(); -+ if(toolbar != NULL) { -+ if (gui.vimWindow->Lock()) { -+ toolbar->MoveTo(x, y); -+ toolbar->ResizeTo(w - 1, h - 1); -+ gui.vimWindow->Unlock(); -+ } -+ } -+} -+ -+#if defined(FEAT_GUI_TABLINE) || defined(PROTO) -+ -+/* -+ * Show or hide the tabline. -+ */ -+ void -+gui_mch_show_tabline(int showit) -+{ -+ VimTabLine *tabLine = gui.vimForm->TabLine(); -+ -+ if (tabLine == NULL) -+ return; -+ -+ if (!showit != !gui.vimForm->IsShowingTabLine()) { -+ gui.vimForm->SetShowingTabLine(showit != 0); -+ gui.tabline_height = gui.vimForm->TablineHeight(); -+ } -+} -+ -+ void -+gui_mch_set_tabline_pos(int x, int y, int w, int h) -+{ -+ VimTabLine *tabLine = gui.vimForm->TabLine(); -+ if(tabLine != NULL) { -+ if (gui.vimWindow->Lock()) { -+ tabLine->MoveTo(x, y); -+ tabLine->ResizeTo(w - 1, h - 1); -+ gui.vimWindow->Unlock(); -+ } -+ } -+} -+ -+/* -+ * Return TRUE when tabline is displayed. -+ */ -+ int -+gui_mch_showing_tabline() -+{ -+ VimTabLine *tabLine = gui.vimForm->TabLine(); -+ return tabLine != NULL && gui.vimForm->IsShowingTabLine(); -+} -+ -+/* -+ * Update the labels of the tabline. -+ */ -+ void -+gui_mch_update_tabline() -+{ -+ tabpage_T *tp; -+ int nr = 0; -+ int curtabidx = 0; -+ -+ VimTabLine *tabLine = gui.vimForm->TabLine(); -+ -+ if (tabLine == NULL) -+ return; -+ -+ gui.vimWindow->Lock(); -+ -+ /* Add a label for each tab page. They all contain the same text area. */ -+ for (tp = first_tabpage; tp != NULL; tp = tp->tp_next, ++nr) { -+ if (tp == curtab) -+ curtabidx = nr; -+ -+ BTab* tab = tabLine->TabAt(nr); -+ -+ if (tab == NULL) { -+ tab = new VimTabLine::VimTab(); -+ tabLine->AddTab(NULL, tab); -+ } -+ -+ get_tabline_label(tp, FALSE); -+ tab->SetLabel((const char*)NameBuff); -+ tabLine->Invalidate(); -+ } -+ -+ /* Remove any old labels. */ -+ while (nr < tabLine->CountTabs()) -+ tabLine->RemoveTab(nr); -+ -+ if(tabLine->Selection() != curtabidx) -+ tabLine->Select(curtabidx); -+ -+ gui.vimWindow->Unlock(); -+} -+ -+/* -+ * Set the current tab to "nr". First tab is 1. -+ */ -+ void -+gui_mch_set_curtab(int nr) -+{ -+ VimTabLine *tabLine = gui.vimForm->TabLine(); -+ if(tabLine == NULL) -+ return; -+ -+ gui.vimWindow->Lock(); -+ -+ if(tabLine->Selection() != nr -1) -+ tabLine->Select(nr -1); -+ -+ gui.vimWindow->Unlock(); -+} -+ -+#endif //FEAT_GUI_TABLINE -diff --git a/src/gui_haiku.h b/src/gui_haiku.h -new file mode 100644 -index 0000000..414d127 ---- /dev/null -+++ b/src/gui_haiku.h -@@ -0,0 +1,51 @@ -+/* 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. -+ * -+ * Haiku GUI. -+ * -+ * Based on "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; -+struct BPictureButton; -+ -+/* 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 BPictureButton BPictureButton; -+typedef struct VimWindow VimWindow; -+typedef struct VimFormView VimFormView; -+typedef struct VimTextAreaView VimTextAreaView; -+typedef struct VimApp VimApp; -+typedef struct VimScrollBar VimScrollBar; -+ -+#endif -diff --git a/src/os_haiku.h b/src/os_haiku.h -new file mode 100644 -index 0000000..c9bfe75 ---- /dev/null -+++ b/src/os_haiku.h -@@ -0,0 +1,29 @@ -+/* vi:set ts=8 sts=4 sw=4: -+ * -+ * VIM - Vi IMproved by Bram Moolenaar -+ * Haiku port by Siarzhuk Zharski -+ * -+ * Do ":help uganda" in Vim to read copying and usage conditions. -+ * Do ":help credits" in Vim to see a list of people who contributed. -+ */ -+ -+/* -+ * os_haiku.h -+ */ -+ -+#define USE_TERM_CONSOLE -+ -+#define USR_VIM_DIR "$BE_USER_SETTINGS/vim" -+ -+#define USR_EXRC_FILE USR_VIM_DIR "/exrc" -+#define USR_VIMRC_FILE USR_VIM_DIR "/vimrc" -+#define USR_GVIMRC_FILE USR_VIM_DIR "/gvimrc" -+#define VIMINFO_FILE USR_VIM_DIR "/viminfo" -+ -+#ifdef RUNTIME_GLOBAL -+# define DFLT_RUNTIMEPATH USR_VIM_DIR "/vimfiles," RUNTIME_GLOBAL \ -+ ",$VIMRUNTIME," RUNTIME_GLOBAL "/after," USR_VIM_DIR "/vimfiles/after" -+#else -+# define DFLT_RUNTIMEPATH USR_VIM_DIR "/vimfiles," "$VIM/vimfiles" \ -+ ",$VIMRUNTIME," "$VIM/vimfiles/after," USR_VIM_DIR "/vimfiles/after" -+#endif -diff --git a/src/os_haiku.rdef b/src/os_haiku.rdef -new file mode 100644 -index 0000000..bf55aa9 ---- /dev/null -+++ b/src/os_haiku.rdef -@@ -0,0 +1,143 @@ -+/* -+ * os_haiku.rdef -+ */ -+ -+resource app_signature "application/x-vnd.Haiku-Vim-8"; -+ -+resource app_version { -+ major = @MAJOR@, -+ middle = @MIDDLE@, -+ minor = @MINOR@, -+ -+ variety = B_APPV_FINAL, -+ internal = 0, -+ -+ short_info = "VIM Editor", -+ long_info = "VI Improved Editor by Bram Moolenaar et al." -+}; -+ -+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" -+}; -+ -+resource vector_icon { -+ $"6E636966050501020006023B8CFD3CB8E4BF59B63E2F604BACDB47A13E00FFFF" -+ $"FFFF909DA702000603BAF8BA3CE3F6BF8EB9BDA8484BC75C4AEA1200C1C7CC79" -+ $"D9E0E5FFC1C7CC020006020000003DC000C000000000004C000049FFFF00B3FF" -+ $"B3FF026C52020006023BD04F3BD04FBED4133ED4134B6000462FB00053AB53FF" -+ $"007F00060618FFFCFFFF63FF282528252725262726262627262B262B262C282D" -+ $"272D282D2B2B582B582B592D5A2C5A2D5A2F5A2F5A305ABA2659315ABA26595E" -+ $"2D5E2D5F2C5F2A5F2B5F2A5F275F275F265D255E255D254A254A254925482748" -+ $"264827482B482B482C4A2D492D4A2D4C3A3F2D3C2D3C2D3D2D3E2B3E2C3E2B3E" -+ $"273E273E263C253D253C250618FFFCFFFF63FF28252825272526272626262726" -+ $"2B262B262C282D272D282D2B2B582B582B592D5A2C5A2D5A2F5A2F5A305ABA26" -+ $"59315ABA26595E2D5E2D5F2C5F2A5F2B5F2A5F275F275F265D255E255D254A25" -+ $"4A254925482748264827482B482B482C4A2D492D4A2D4C3A3F2D3C2D3C2D3D2D" -+ $"3E2B3E2C3E2B3E273E273E263C253D253C250A08BEA359BE3D593C5A415AC03B" -+ $"59BFD559434C404C06218A88888888C83E3F02484CC1D359C16D445A49C36B59" -+ $"C305C3CA50C5C8C50359C49D4C5A51C69B59C635C6FA50C8F8C83359C7CD545A" -+ $"59C9CB59C965CA6B4DCA6B4DCA804C5A4C584C584C574CC86D4DC8D34DC86D4D" -+ $"C73B524C534C524C504C504C4F4CC53D4DC5A34DC53D4DC40B4B4C0608EBECC0" -+ $"B64AC0B64AC11C4AC13349C14848C0F847C15E47C0F847C092C01648C02C47C0" -+ $"1648C00149C0504ABFEA4AC0504A0A04405E5E40402222400A0A000105180015" -+ $"01178600040A0001051815FF01178400040A030105000A0401051001157C0004" -+ $"0A000100381D1F001501178600040A000100381D1F15FF01178300040A010101" -+ $"201D1F0A020101301D1F01157E00040A0003020304381D1F15FF01178400040A" -+ $"0203020304281D1F15FF" -+}; -+ -+resource(1, "builtin-tools") #'PNG ' array { -+ $"89504E470D0A1A0A0000000D494844520000022E0000001208030000004BB3A5" -+ $"1200000300504C5445000000800000008000808000000080800080008080C0C0" -+ $"C0C0DCC0A6CAF0402000602000802000A02000C02000E0200000400020400040" -+ $"4000604000804000A04000C04000E04000006000206000406000606000806000" -+ $"A06000C06000E06000008000208000408000608000808000A08000C08000E080" -+ $"0000A00020A00040A00060A00080A000A0A000C0A000E0A00000C00020C00040" -+ $"C00060C00080C000A0C000C0C000E0C00000E00020E00040E00060E00080E000" -+ $"A0E000C0E000E0E000000040200040400040600040800040A00040C00040E000" -+ $"40002040202040402040602040802040A02040C02040E0204000404020404040" -+ $"4040604040804040A04040C04040E04040006040206040406040606040806040" -+ $"A06040C06040E06040008040208040408040608040808040A08040C08040E080" -+ $"4000A04020A04040A04060A04080A040A0A040C0A040E0A04000C04020C04040" -+ $"C04060C04080C040A0C040C0C040E0C04000E04020E04040E04060E04080E040" -+ $"A0E040C0E040E0E040000080200080400080600080800080A00080C00080E000" -+ $"80002080202080402080602080802080A02080C02080E0208000408020408040" -+ $"4080604080804080A04080C04080E04080006080206080406080606080806080" -+ $"A06080C06080E06080008080208080408080608080808080A08080C08080E080" -+ $"8000A08020A08040A08060A08080A080A0A080C0A080E0A08000C08020C08040" -+ $"C08060C08080C080A0C080C0C080E0C08000E08020E08040E08060E08080E080" -+ $"A0E080C0E080E0E0800000C02000C04000C06000C08000C0A000C0C000C0E000" -+ $"C00020C02020C04020C06020C08020C0A020C0C020C0E020C00040C02040C040" -+ $"40C06040C08040C0A040C0C040C0E040C00060C02060C04060C06060C08060C0" -+ $"A060C0C060C0E060C00080C02080C04080C06080C08080C0A080C0C080C0E080" -+ $"C000A0C020A0C040A0C060A0C080A0C0A0A0C0C0A0C0E0A0C000C0C020C0C040" -+ $"C0C060C0C080C0C0A0C0C0FFFBF0A0A0A4808080FF000000FF00FFFF000000FF" -+ $"FF00FF00FFFFFFFFFF58D234440000000874524E53FFFFFFFFFFFFFF00DE83BD" -+ $"59000000097048597300000B1200000B1201D2DD7EFC0000070D494441546881" -+ $"DD994B6E23390C86695880F6BDCD19BCCD3AD7CA7DB4CD197C965EE7044619D0" -+ $"F0299192AA5C9907D018762776D12A3DA8AF7E520E64B382FFB792FF004BCD4E" -+ $"DF02C1DC0717347779C3FFDB8D5F43A3705900FE8838FCDB868119C3F3E32EDA" -+ $"BB5A1897CA916A1B566CA49DED7865B2E3E930FC6397A9AAEDE232F10409EA37" -+ $"5B851A70793C020BB70C1B8CB4C436057EFFF6BCACE0BD0CAF75159D21567B6D" -+ $"B2BB9EC73AF7E89C21013E3EF03F1A4CD339BDA77E390523594BE549EA7E55DD" -+ $"E8793B68FEF332D4D3BD72BFE1B2D68D19171A87861F37ADB4163A3FEB87E6A7" -+ $"06411B06146E37D8B60D6E9E176C121A212D81976930BAE5C231A657895D5B80" -+ $"8735AE6BD5068729057FCC318FB5183DC682BB8924AC4D5AB456557F9771D647" -+ $"066E0B378A6491FD65381017DDB2793BD2674A9F64E14950CF67DFD8941D3D5D" -+ $"37DA62B1BB1B9ADFE4452BA3B3C41649D58BE6B77E58065C36B3EEC26C856D7A" -+ $"3E2A332ECFA73E3BBD53EE955F5BB8F939B3F85B749D2DDA003A0A5E546B392D" -+ $"6CE11962C1FD4412D6664C01702B990E4FA5C6591F18F4CDF1913475B1597975" -+ $"498A4BB3B632E7EA7B5F5C2E620A83C4C0ED2AFB7BBD4268157191693455129A" -+ $"BF6BD329C265918F461496EAF23219E5E7B3549977BF036FE1DFEDE9ACB2E7FB" -+ $"819736D9B76152F8C7B6B95E5AE06DA99327C682FBF9289E04B46B306D2519AB" -+ $"6480361D9A8ABDC0F291ABFE8271F916D9A849D505432FEA42D3E4965E5D1C2E" -+ $"B486CE463247C025E54159436982B898395C26759970A9BE9386CB948FC64473" -+ $"A676912AC06DFA53E5A51753C0A4D08F17730E6A734C81F7C94853BC3C8AF44B" -+ $"79A9974B5C18EE6573795C86041E49405ACAE68CC72168AEF9FAF686BF4D5DDC" -+ $"74CB98902AB8D7EA70112E0ACE076B1776DEFB7EA4BBE1B2509784893799BCA4" -+ $"76ED71416971BBCEEA623DF1B21197DB50D2840662853E2A2E19E95C2C6883BA" -+ $"A4B6DB63EDB23A19C536BCBF5E5ECAF329F2D22704C221DEE670113016C540DD" -+ $"C18576B7B0BA202CC2CB85B410F9B085F1D5E3228F00F45880CC221891A04EA1" -+ $"E55B7F181705081B15F12C71A9DC41FBC454489B414F4685D0D80A4E3F3E1789" -+ $"9FFA1D7521509ABCC89BF439E2E28B9BA82E0D97F844AD6A17E969D09F1E3448" -+ $"699EA2B0100FC9793C44E7E1B02DA50BA6A3E621655179E9B858FD32D1E11C75" -+ $"74B567B0CB0AC55B4EA37425106AFDEC1D35F2A1692DF24224E8BBB221840117" -+ $"038871F9DEC385122A83AF2E914B6B06E06B17C605E70F776760B8B45A32292E" -+ $"76D01E710907F0E1F4B4A72ECEE3594D417103762C223D688A4B5497391F9CF0" -+ $"80E1622393B290C0607CF2A1BA4CB84CAE6E8A4B257929242EF4CEE078F48599" -+ $"E712F900417117976DC3021AA9907F084703E885BA48426D5955E432F78B880B" -+ $"DD8AFEFB7BB32B182EDD64844299A74CB8D0C1903ED13594A1D47DA12E34B8B7" -+ $"D223E28F0249C5A5056DA52EAEA7AF2FEEE88C87BEA42364DCC83D40D97059D5" -+ $"2E7BC9A8F62D51EBC9A8B2C0DB01C9E8E80BEB7213F880F032E18240081C1D17" -+ $"03E8585D72FE91BA6805E6707987515D4CE9932F598637EECCC7B8F8134D5DA9" -+ $"8BC7E5F1F86A56DCF13AE022EAD282C6B844010CDC15DAFD331EE5C51FA5537D" -+ $"3C727E704A7A3ED9B53A198DA56E0FEB949F7AA92B0072F552A463CA8C7D6156" -+ $"BB0C7CF00E1EE0029BA41E4D47C8E9E6D5E5089755ED62CDD6B80CF21270F9F5" -+ $"ABE3C2E7202970F3E8695B2CEAD28AD81D7571C9E8FEF5B5C4C59BA94B0B9AE0" -+ $"1204D075F478281CAF3DB9A5A3968D522DC8CB0379C1B4C4BCACBF77C9FE201D" -+ $"4F46D666719016846C9D720CF234C8C968E443867BDBC1C578E927A306D0212E" -+ $"35984D09DCC54B5CDEF770E95FB3B883B439CCD3BE7751DD61D3A3D89EBAECE0" -+ $"32ABCB58EA46010C1D8D70EC7A7AADDB78C1D9154E095E5D2EFAAA87AAF990CC" -+ $"59B9D95E1BE0546747EA6CDFBB381AD2E4E158D02ADFDE022F0E17C9A81E5703" -+ $"E8B07681F12EF9C85D2C71C130BAEF78F670B1435083A37DABDB1D599391952F" -+ $"14BA78F0E1DD7500ADE73CE1A20F00DE2B995652909F22DC7B2784C2394FE6BF" -+ $"01683A0237985717AC5D742297A02E1185D196B8F0BBFE374DB730A561F6F458" -+ $"445E3C2E8155C65501A24612D60997D55DAE3399EF1A9769C7965B2867A0E2E2" -+ $"A31E7759F41835B4E9C7A71120F0EA02E51017BA45FF3253665C5C19AB70BCF6" -+ $"642D5B2423411F8C6B97868B8D9E5BED326AB84637E032B5E94A648AED17C634" -+ $"CC1E178B7D5C661302A891ECBE4E07E6591FD81A9781B3A5A339E749F94BFF32" -+ $"75AED701A01D71099DF832450BF94900492EBA3109273CD9FE02C03909FA6024" -+ $"912D194D339C0EC9D6CCAD7AD166F2C485312E93671150B617B88C8D86DC731A" -+ $"1767E7EEF90FEC3599BB77B416E3EAE7689CF114DBE3E262B898CB34FECE845E" -+ $"4CFAEF79764372DC201F65AC97B792C14FE6F387DBB4F83918273C6E9B866FD9" -+ $"FF17F6CF36F92F1B9E631E8B8F3FBC0000000049454E44AE426082" -+}; -diff --git a/src/proto/gui_haiku.pro b/src/proto/gui_haiku.pro -new file mode 100644 -index 0000000..deb412b ---- /dev/null -+++ b/src/proto/gui_haiku.pro -@@ -0,0 +1,92 @@ -+/* gui_haiku.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_rgb(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_mousehide __ARGS((int hide)); -+ -+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, int ex_cmd)); -+ -+void im_set_position __ARGS((int row, int col)); -+void im_set_active __ARGS((int activate)); -+int im_get_status __ARGS(()); -+ -+void gui_mch_show_toolbar __ARGS((int showit)); -+void gui_mch_set_toolbar_pos __ARGS((int x, int y, int w, int h)); -+ -+void gui_mch_show_tabline __ARGS((int showit)); -+void gui_mch_set_tabline_pos __ARGS((int x, int y, int w, int h)); -+int gui_mch_showing_tabline __ARGS((void)); -+void gui_mch_update_tabline __ARGS((void)); -+void gui_mch_set_curtab __ARGS((int nr)); -+// char_u *gui_mch_font_dialog __ARGS((char_u *oldval)); --- -2.21.0 - - -From 5ec6c5edade39807a7e5e2e77f7f3b062d14e375 Mon Sep 17 00:00:00 2001 -From: Adrien Destugues -Date: Wed, 1 May 2019 09:52:09 +0200 -Subject: Import 8.0 patch: modified files. - - -diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt -index f728c12..f660e52 100644 ---- a/runtime/doc/eval.txt -+++ b/runtime/doc/eval.txt -@@ -10490,12 +10490,14 @@ gui_gnome Compiled with Gnome support (gui_gtk is also defined). - gui_gtk Compiled with GTK+ GUI (any version). - gui_gtk2 Compiled with GTK+ 2 GUI (gui_gtk is also defined). - gui_gtk3 Compiled with GTK+ 3 GUI (gui_gtk is also defined). -+gui_haiku Compiled with Haiku GUI. - gui_mac Compiled with Macintosh GUI. - gui_motif Compiled with Motif GUI. - gui_photon Compiled with Photon GUI. - gui_running Vim is running in the GUI, or it will start soon. - gui_win32 Compiled with MS Windows Win32 GUI. - gui_win32s idem, and Win32s system being used (Windows 3.1) -+haiku Haiku version of Vim. - hangul_input Compiled with Hangul input support. |hangul| - hpux HP-UX version of Vim. - iconv Can use iconv() for conversion. -diff --git a/runtime/doc/gui.txt b/runtime/doc/gui.txt -index 2a8a70d..f21f17e 100644 ---- a/runtime/doc/gui.txt -+++ b/runtime/doc/gui.txt -@@ -102,6 +102,7 @@ Recommended place for your personal GUI initializations: - or $VIM/_gvimrc - Amiga s:.gvimrc, home:.gvimrc, home:vimfiles:gvimrc - or $VIM/.gvimrc -+ Haiku $HOME/config/settings/vim/gvimrc - - The personal initialization files are searched in the order specified above - and only the first one that is found is read. -diff --git a/runtime/doc/help.txt b/runtime/doc/help.txt -index c8ff75a..a4046c8 100644 ---- a/runtime/doc/help.txt -+++ b/runtime/doc/help.txt -@@ -202,6 +202,7 @@ Remarks about specific systems ~ - |os_os2.txt| OS/2 - |os_qnx.txt| QNX - |os_risc.txt| RISC-OS -+|os_haiku.txt| Haiku - |os_unix.txt| Unix - |os_vms.txt| VMS - |os_win32.txt| MS-Windows 95/98/NT -diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt -index 985137b..0abf8d6 100644 ---- a/runtime/doc/options.txt -+++ b/runtime/doc/options.txt -@@ -3688,7 +3688,7 @@ A jump table for the options with a short description can be found at |Q_op|. - 'guitablabel' can be used to change the text in the labels. - When 'e' is missing a non-GUI tab pages line may be used. - The GUI tabs are only supported on some systems, currently -- GTK, Motif, Mac OS/X and MS-Windows. -+ GTK, Motif, Mac OS/X, Haiku and MS-Windows. - *'go-f'* - 'f' Foreground: Don't use fork() to detach the GUI from the shell - where it was started. Use this for programs that wait for the -@@ -6094,7 +6094,12 @@ A jump table for the options with a short description can be found at |Q_op|. - $VIM/vimfiles, - $VIMRUNTIME, - $VIM/vimfiles/after, -- sys$login:vimfiles/after") -+ sys$login:vimfiles/after" -+ Haiku: "$BE_USER_SETTINGS/vim, -+ $VIM/vimfiles, -+ $VIMRUNTIME, -+ $VIM/vimfiles/after, -+ $BE_USER_SETTINGS/vim/after") - global - This is a list of directories which will be searched for runtime - files: -@@ -7540,6 +7545,7 @@ A jump table for the options with a short description can be found at |Q_op|. - on MiNT: "vt52" - on MS-DOS: "pcterm" - on OS/2: "os2ansi" -+ on Haiku: "xterm" - on Unix: "ansi" - on VMS: "ansi" - on Win 32: "win32") -diff --git a/runtime/doc/starting.txt b/runtime/doc/starting.txt -index 595f595..c16b07a 100644 ---- a/runtime/doc/starting.txt -+++ b/runtime/doc/starting.txt -@@ -811,6 +811,7 @@ accordingly. Vim proceeds in this order: - or $VIM/_vimrc - Amiga s:.vimrc, home:.vimrc, home:vimfiles:vimrc - or $VIM/.vimrc -+ Haiku $HOME/config/settings/vim/vimrc - - The files are searched in the order specified above and only the first - one that is found is read. -@@ -857,6 +858,7 @@ accordingly. Vim proceeds in this order: - "$HOME/_vimrc" (for MS-DOS and Win32) (*) - "$HOME/vimfiles/vimrc" (for MS-DOS and Win32) (*) - "$VIM/_vimrc" (for MS-DOS and Win32) (*) -+ "$HOME/config/settings/vim/vimrc" (for Haiku) (*) - Note: For Unix, OS/2 and Amiga, when ".vimrc" does not exist, - "_vimrc" is also tried, in case an MS-DOS compatible file - system is used. For MS-DOS and Win32 ".vimrc" is checked -@@ -971,6 +973,7 @@ sessions. Put it in a place so that it will be found by 3b: - ~/.vimrc (Unix and OS/2) - s:.vimrc (Amiga) - $VIM\_vimrc (MS-DOS and Win32) -+ ~/config/settings/vim/vimrc (Haiku) - Note that creating a vimrc file will cause the 'compatible' option to be off - by default. See |compatible-default|. - -diff --git a/runtime/doc/tags b/runtime/doc/tags -index 0c9aa14..30a9e86 100644 ---- a/runtime/doc/tags -+++ b/runtime/doc/tags -@@ -4752,6 +4752,7 @@ GetLatestVimScripts-copyright pi_getscript.txt /*GetLatestVimScripts-copyright* - GetLatestVimScripts_dat pi_getscript.txt /*GetLatestVimScripts_dat* - Gnome gui_x11.txt /*Gnome* - H motion.txt /*H* -+Haiku os_haiku.txt /*Haiku* - I insert.txt /*I* - ICCF uganda.txt /*ICCF* - IM-server mbyte.txt /*IM-server* -@@ -6894,6 +6895,20 @@ g~ change.txt /*g~* - g~g~ change.txt /*g~g~* - g~~ change.txt /*g~~* - h motion.txt /*h* -+haiku-bugs os_haiku.txt /*haiku-bugs* -+haiku-colors os_haiku.txt /*haiku-colors* -+haiku-compiling os_haiku.txt /*haiku-compiling* -+haiku-dragndrop os_haiku.txt /*haiku-dragndrop* -+haiku-fonts os_haiku.txt /*haiku-fonts* -+haiku-general os_haiku.txt /*haiku-general* -+haiku-gui os_haiku.txt /*haiku-gui* -+haiku-launch os_haiku.txt /*haiku-launch* -+haiku-meta os_haiku.txt /*haiku-meta* -+haiku-mouse os_haiku.txt /*haiku-mouse* -+haiku-support-credits os_haiku.txt /*haiku-support-credits* -+haiku-toolbar-images os_haiku.txt /*haiku-toolbar-images* -+haiku-user-settings-dir os_haiku.txt /*haiku-user-settings-dir* -+haiku-vimdir os_haiku.txt /*haiku-vimdir* - hangul hangulin.txt /*hangul* - hangulin.txt hangulin.txt /*hangulin.txt* - has() eval.txt /*has()* -@@ -8029,6 +8044,7 @@ os_390.txt os_390.txt /*os_390.txt* - os_amiga.txt os_amiga.txt /*os_amiga.txt* - os_beos.txt os_beos.txt /*os_beos.txt* - os_dos.txt os_dos.txt /*os_dos.txt* -+os_haiku.txt os_haiku.txt /*os_haiku.txt* - os_mac.txt os_mac.txt /*os_mac.txt* - os_mint.txt os_mint.txt /*os_mint.txt* - os_msdos.txt os_msdos.txt /*os_msdos.txt* -diff --git a/runtime/doc/vi_diff.txt b/runtime/doc/vi_diff.txt -index b71fdbc..ef8af32 100644 ---- a/runtime/doc/vi_diff.txt -+++ b/runtime/doc/vi_diff.txt -@@ -141,6 +141,7 @@ Support for different systems. - - Atari MiNT - - VMS - - BeOS -+ - Haiku - - Macintosh - - Risc OS - - IBM OS/390 -@@ -168,7 +169,7 @@ Graphical User Interface (GUI). |gui| - define your own menus. Better support for CTRL/SHIFT/ALT keys in - combination with special keys and mouse. Supported for various - platforms, such as X11 (with Motif and Athena interfaces), GTK, Win32 -- (Windows 95 and later), BeOS, Amiga and Macintosh. -+ (Windows 95 and later), Haiku, Amiga and Macintosh. - - Multiple windows and buffers. |windows.txt| - Vim can split the screen into several windows, each editing a -diff --git a/runtime/gvimrc_example.vim b/runtime/gvimrc_example.vim -index fa0f685..a7975f9 100644 ---- a/runtime/gvimrc_example.vim -+++ b/runtime/gvimrc_example.vim -@@ -10,6 +10,7 @@ - " for Amiga: s:.gvimrc - " for MS-DOS and Win32: $VIM\_gvimrc - " for OpenVMS: sys$login:.gvimrc -+" for Haiku OS: ~/config/settings/vim/gvimrc - - " Make external commands work through a pipe instead of a pseudo-tty - "set noguipty -diff --git a/runtime/vimrc_example.vim b/runtime/vimrc_example.vim -index b05793b..943b98d 100644 ---- a/runtime/vimrc_example.vim -+++ b/runtime/vimrc_example.vim -@@ -8,6 +8,7 @@ - " for Amiga: s:.vimrc - " for MS-DOS and Win32: $VIM\_vimrc - " for OpenVMS: sys$login:.vimrc -+" for Haiku OS: ~/config/settings/vim/vimrc - - " When started as "evim", evim.vim will already have done these settings, bail - " out. -diff --git a/src/Makefile b/src/Makefile -index 19b59c2..89c689c 100644 ---- a/src/Makefile -+++ b/src/Makefile -@@ -1380,6 +1380,23 @@ CARBONGUI_BUNDLE = gui_bundle - APPDIR = $(VIMNAME).app - CARBONGUI_TESTARG = VIMPROG=../$(APPDIR)/Contents/MacOS/$(VIMTARGET) - -+### Haiku GUI -+HAIKUGUI_SRC = gui.c gui_haiku.cc -+HAIKUGUI_OBJ = objects/gui.o objects/gui_haiku.o -+HAIKUGUI_DEFS = -DFEAT_GUI_HAIKU -+HAIKUGUI_IPATH = -+HAIKUGUI_LIBS_DIR = -+HAIKUGUI_LIBS1 = -lbe -lroot -ltracker -ltranslation -+ifeq ($(strip $(word 1, $(subst -, , $(subst ., , $(shell $(CC) -dumpversion))))), 8) -+HAIKUGUI_LIBS1 += -lsupc++ -lstdc++ -+endif -+HAIKUGUI_LIBS2 = -+HAIKUGUI_INSTALL = install_normal install_haiku_extra -+HAIKUGUI_TARGETS = installglinks_haiku -+HAIKUGUI_MAN_TARGETS = -+HAIKUGUI_TESTTARGET = gui -+HAIKUGUI_BUNDLE = -+ - # All GUI files - ALL_GUI_SRC = gui.c gui_gtk.c gui_gtk_f.c gui_motif.c gui_xmdlg.c gui_xmebw.c gui_athena.c gui_gtk_x11.c gui_x11.c gui_at_sb.c gui_at_fs.c - ALL_GUI_PRO = gui.pro gui_gtk.pro gui_motif.pro gui_xmdlg.pro gui_athena.pro gui_gtk_x11.pro gui_x11.pro gui_w32.pro gui_photon.pro -@@ -3058,6 +3075,9 @@ objects/gui_gtk_gresources.o: auto/gui_gtk_gresources.c - objects/gui_gtk_x11.o: gui_gtk_x11.c - $(CCC) -o $@ gui_gtk_x11.c - -+objects/gui_haiku.o: gui_haiku.cc -+ $(CCC) -o $@ gui_haiku.cc -+ - objects/gui_motif.o: gui_motif.c - $(CCC) -o $@ gui_motif.c - -@@ -3178,6 +3198,9 @@ objects/option.o: option.c - objects/os_beos.o: os_beos.c - $(CCC) -o $@ os_beos.c - -+objects/os_haiku.rsrc: os_haiku.rdef -+ cat $< | $(CCC) -E - | grep -v '^#' | rc -o "$@" - -+ - objects/os_qnx.o: os_qnx.c - $(CCC) -o $@ os_qnx.c - -@@ -3404,6 +3427,63 @@ $(APPDIR)/Contents: - - - ############################################################################### -+### -+### Haiku installation -+### -+### This rule: -+### - add resources to already installed vim binary to avoid stripping -+### them during install; -+### - copy rgb.txt to runtime directory; -+### - update system MIME database with info about vim application. -+### -+install_haiku_extra: $(DEST_BIN)/$(VIMTARGET) objects/os_haiku.rsrc -+ xres -o $(DEST_BIN)/$(VIMTARGET) objects/os_haiku.rsrc -+ $(INSTALL_DATA) $(SCRIPTSOURCE)/rgb.txt $(DEST_RT) -+ mimeset $(DEST_BIN)/$(VIMTARGET) -+ -+### -+### List of g*-links that should be replaced with shell script equivalents. -+### This solves the problem of them from Tracker. -+### -+HAIKU_GLINKS = $(DEST_BIN)/$(GVIMTARGET) \ -+ $(DEST_BIN)/$(GVIEWTARGET) \ -+ $(DEST_BIN)/$(GVIMDIFFTARGET) \ -+ $(DEST_BIN)/$(RGVIMTARGET) \ -+ $(DEST_BIN)/$(RGVIEWTARGET) -+### -+### This rule: -+### - Replace gvim link with copy of vim binary. -+### - Replace g*-links with shell script equivalents to solve the problem -+### of calling them from Tracker, -+### - Add icon resources to mentioned g*-link shell scripts -+### - in case gui-less vim.con executable available use it. -+### -+installglinks_haiku: $(HAIKU_GLINKS) install_haiku_extra -+ @catattr -r "BEOS:ICON" $(DEST_BIN)/$(GVIMTARGET) > ~icon.attr -+ for i in $(HAIKU_GLINKS); do \ -+ rm $$i ; \ -+ echo "#!/bin/sh" > $$i ; \ -+ case $$i in \ -+ $(DEST_BIN)/$(GVIMTARGET)) \ -+ cp $(DEST_BIN)/$(VIMTARGET) $$i ; \ -+ if [ -f $(VIMTARGET).con ] ; then \ -+ $(STRIP) $(VIMTARGET).con ; \ -+ mv $(VIMTARGET).con $(DEST_BIN)/$(VIMTARGET) ; \ -+ fi ;; \ -+ $(DEST_BIN)/$(GVIEWTARGET)) printf "%s -R %c%c" $(GVIMTARGET) '$$' '*' >> $$i;; \ -+ $(DEST_BIN)/$(GVIMDIFFTARGET)) printf "%s -d %c%c" $(GVIMTARGET) '$$' '*' >> $$i;; \ -+ $(DEST_BIN)/$(RGVIMTARGET)) printf "%s -Z %c%c" $(GVIMTARGET) '$$' '*' >> $$i;; \ -+ $(DEST_BIN)/$(RGVIEWTARGET)) printf "%s -Z -R %c%c" $(GVIMTARGET) '$$' '*' >> $$i;; \ -+ *) printf "%s %c%c" $(GVIMTARGET) '$$' '*' >> $$i;; \ -+ esac ; \ -+ chmod $(BINMOD) $$i ; \ -+ addattr -f ~icon.attr -t \'VICN\' BEOS:ICON $$i ; \ -+ done -+ addattr -f ~icon.attr -t \'VICN\' BEOS:ICON $(DEST_BIN)/$(VIMNAME)tutor -+ @rm ~icon.attr -+ -+############################################################################### -+ - ### (automatically generated by 'make depend') - ### Dependencies: - objects/arabic.o: arabic.c vim.h protodef.h auto/config.h feature.h os_unix.h \ -diff --git a/src/configure.ac b/src/configure.ac -index 2a3bc33..bfed5a7 100644 ---- a/src/configure.ac -+++ b/src/configure.ac -@@ -154,6 +154,12 @@ case `uname` in - *) BEOS=no; AC_MSG_RESULT(no);; - esac - -+AC_MSG_CHECKING(for Haiku) -+case `uname` in -+ Haiku) HAIKU=yes; AC_MSG_RESULT(yes);; -+ *) HAIKU=no; AC_MSG_RESULT(no);; -+esac -+ - dnl If QNX is found, assume we don't want to use Xphoton - dnl unless it was specifically asked for (--with-x) - AC_MSG_CHECKING(for QNX) -@@ -2033,7 +2039,11 @@ fi - - if test "$enable_channel" = "yes"; then - dnl On Solaris we need the socket and nsl library. -- AC_CHECK_LIB(socket, socket) -+ if test "x$HAIKU" = "xyes"; then -+ AC_CHECK_LIB(network, socket) -+ else -+ AC_CHECK_LIB(socket, socket) -+ fi - AC_CHECK_LIB(nsl, gethostbyname) - AC_MSG_CHECKING(whether compiling with process communication is possible) - AC_TRY_LINK([ -@@ -2315,11 +2325,11 @@ if test "x$with_x" = xno -a "x$with_x_arg" = xyes; then - AC_MSG_ERROR([could not configure X]) - fi - --test "x$with_x" = xno -a "x$MACOS_X" != "xyes" -a "x$QNX" != "xyes" && enable_gui=no -+test "x$with_x" = xno -a "x$HAIKU" != "xyes" -a "x$MACOS_X" != "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/gtk2/gnome2/gtk3/motif/athena/neXtaw/photon/carbon]], , enable_gui="auto") -+ [ --enable-gui[=OPTS] X11 GUI. [default=auto] [OPTS=auto/no/gtk2/gnome2/gtk3/motif/athena/neXtaw/haiku/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. -@@ -2334,10 +2344,23 @@ SKIP_MOTIF=YES - SKIP_ATHENA=YES - SKIP_NEXTAW=YES - SKIP_PHOTON=YES -+SKIP_HAIKU=YES - SKIP_CARBON=YES - GUITYPE=NONE - --if test "x$QNX" = "xyes" -a "x$with_x" = "xno" ; then -+if test "x$HAIKU" = "xyes"; then -+ SKIP_HAIKU= -+ case "$enable_gui_canon" in -+ no) AC_MSG_RESULT(no GUI support) -+ SKIP_HAIKU=YES ;; -+ yes|"") AC_MSG_RESULT(yes - automatic GUI support) ;; -+ auto) AC_MSG_RESULT(auto - automatic GUI support) ;; -+ haiku) AC_MSG_RESULT(Haiku GUI support) ;; -+ *) AC_MSG_RESULT([Sorry, $enable_gui GUI is not supported]) -+ SKIP_HAIKU=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) -@@ -2503,6 +2526,7 @@ if test "x$MACOS_X" = "xyes" -a -z "$SKIP_CARBON" -a "x$CARBON" = "xyes"; then - SKIP_ATHENA=YES; - SKIP_NEXTAW=YES; - SKIP_PHOTON=YES; -+ SKIP_HAIKU=YES; - SKIP_CARBON=YES - fi - -@@ -3121,6 +3145,11 @@ if test "x$GUITYPE:$enable_fontset" = "xGTK:yes"; then - enable_fontset="no" - fi - -+dnl There is no test for the Haiku GUI, if it's selected it's used -+if test -z "$SKIP_HAIKU"; then -+ GUITYPE=HAIKUGUI -+fi -+ - if test -z "$SKIP_PHOTON"; then - GUITYPE=PHOTONGUI - fi -diff --git a/src/evalfunc.c b/src/evalfunc.c -index e65ab94..0346fc7 100644 ---- a/src/evalfunc.c -+++ b/src/evalfunc.c -@@ -6203,6 +6203,9 @@ f_has(typval_T *argvars, typval_T *rettv) - #ifdef __BEOS__ - "beos", - #endif -+#ifdef __HAIKU__ -+ "haiku", -+#endif - #if defined(BSD) && !defined(MACOS_X) - "bsd", - #endif -@@ -6395,6 +6398,9 @@ f_has(typval_T *argvars, typval_T *rettv) - #ifdef FEAT_GUI_GNOME - "gui_gnome", - #endif -+#ifdef FEAT_GUI_HAIKU -+ "gui_haiku", -+#endif - #ifdef FEAT_GUI_MAC - "gui_mac", - #endif -diff --git a/src/ex_cmds.c b/src/ex_cmds.c -index 991dc45..ea23d6b 100644 ---- a/src/ex_cmds.c -+++ b/src/ex_cmds.c -@@ -14,6 +14,9 @@ - #include "vim.h" - #include "version.h" - -+#include -+#include -+ - #ifdef FEAT_FLOAT - # include - #endif -@@ -1964,6 +1967,8 @@ write_viminfo(char_u *file, int forceit) - int hidden = FALSE; - #endif - -+char* filenameSeparatorPos; -+ - if (no_viminfo()) - return; - -@@ -1971,6 +1976,19 @@ write_viminfo(char_u *file, int forceit) - if (fname == NULL) - return; - -+ /* Ensure that configuration folder(for viminfo) exist */ -+ filenameSeparatorPos = strrchr(fname, '/'); -+ if(filenameSeparatorPos != NULL && -+ filenameSeparatorPos - (char*)fname > 1) { -+ // > 1 because root directory always exists anyway -+ *filenameSeparatorPos = '\0'; -+ // 1020))) - # define FEAT_GUI_TABLINE -@@ -702,7 +712,8 @@ - */ - #if defined(FEAT_NORMAL) - # define FEAT_BROWSE_CMD --# if 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_GUI_MSWIN) || defined(FEAT_GUI_MOTIF) || defined(FEAT_GUI_ATHENA) \ -+ || defined(FEAT_GUI_GTK) || defined(FEAT_GUI_HAIKU) || defined(FEAT_GUI_PHOTON) || defined(FEAT_GUI_MAC) - # define FEAT_BROWSE - # endif - #endif -@@ -727,6 +738,7 @@ - && defined(HAVE_X11_XPM_H)) \ - || defined(FEAT_GUI_GTK) \ - || defined(FEAT_GUI_PHOTON) \ -+ || defined(FEAT_GUI_HAIKU) \ - || defined(FEAT_GUI_MSWIN) \ - || defined(FEAT_GUI_MAC) - # define FEAT_CON_DIALOG -@@ -744,7 +756,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_HAIKU) - # define FEAT_GUI_TEXTDIALOG - # ifndef ALWAYS_USE_GUI - # define FEAT_CON_DIALOG -diff --git a/src/gui.c b/src/gui.c -index 471202b..82c89b6 100644 ---- a/src/gui.c -+++ b/src/gui.c -@@ -441,7 +441,7 @@ gui_init_check(void) - gui.menu_width = 0; - # endif - #endif --#if defined(FEAT_TOOLBAR) && (defined(FEAT_GUI_MOTIF) || defined(FEAT_GUI_ATHENA)) -+#if defined(FEAT_TOOLBAR) && (defined(FEAT_GUI_MOTIF) || defined(FEAT_GUI_ATHENA) || defined(FEAT_GUI_HAIKU)) - gui.toolbar_height = 0; - #endif - #if defined(FEAT_FOOTER) && defined(FEAT_GUI_MOTIF) -@@ -1386,10 +1386,10 @@ gui_position_components(int total_width UNUSED) - text_area_y += gui.tabline_height; - #endif - --#if defined(FEAT_TOOLBAR) && (defined(FEAT_GUI_MOTIF) || defined(FEAT_GUI_ATHENA)) -+#if defined(FEAT_TOOLBAR) && (defined(FEAT_GUI_MOTIF) || defined(FEAT_GUI_ATHENA) || defined(FEAT_GUI_HAIKU)) - if (vim_strchr(p_go, GO_TOOLBAR) != NULL) - { --# ifdef FEAT_GUI_ATHENA -+# if defined(FEAT_GUI_ATHENA) || defined(FEAT_GUI_HAIKU) - gui_mch_set_toolbar_pos(0, text_area_y, - gui.menu_width, gui.toolbar_height); - # endif -@@ -1397,6 +1397,13 @@ gui_position_components(int total_width UNUSED) - } - #endif - -+# if defined(FEAT_GUI_TABLINE) && (defined(FEAT_GUI_HAIKU)) -+ gui_mch_set_tabline_pos(0, text_area_y, -+ gui.menu_width, gui.tabline_height); -+ if (gui_has_tabline()) -+ text_area_y += gui.tabline_height; -+#endif -+ - text_area_width = gui.num_cols * gui.char_width + gui.border_offset * 2; - text_area_height = gui.num_rows * gui.char_height + gui.border_offset * 2; - -@@ -1468,7 +1475,7 @@ gui_get_base_height(void) - # endif - # endif - # if defined(FEAT_GUI_TABLINE) && (defined(FEAT_GUI_MSWIN) \ -- || defined(FEAT_GUI_MOTIF)) -+ || defined(FEAT_GUI_MOTIF) || defined(FEAT_GUI_HAIKU)) - if (gui_has_tabline()) - base_height += gui.tabline_height; - # endif -@@ -1511,6 +1518,10 @@ again: - new_pixel_height = 0; - busy = TRUE; - -+ #ifdef FEAT_GUI_HAIKU -+ vim_lock_screen(); -+ #endif -+ - /* Flush pending output before redrawing */ - out_flush(); - -@@ -1533,6 +1544,10 @@ again: - || gui.num_rows != Rows || gui.num_cols != Columns) - shell_resized(); - -+#ifdef FEAT_GUI_HAIKU -+ vim_unlock_screen(); -+#endif -+ - gui_update_scrollbars(TRUE); - gui_update_cursor(FALSE, TRUE); - #if defined(FEAT_XIM) && !defined(FEAT_GUI_GTK) -@@ -4264,9 +4279,9 @@ gui_update_scrollbars( - y += gui.menu_height; - #endif - --#if defined(FEAT_TOOLBAR) && (defined(FEAT_GUI_MSWIN) || defined(FEAT_GUI_ATHENA)) -+#if defined(FEAT_TOOLBAR) && (defined(FEAT_GUI_MSWIN) || defined(FEAT_GUI_ATHENA) || defined(FEAT_GUI_HAIKU)) - if (vim_strchr(p_go, GO_TOOLBAR) != NULL) --# ifdef FEAT_GUI_ATHENA -+# if defined(FEAT_GUI_ATHENA) || defined(FEAT_GUI_HAIKU) - y += gui.toolbar_height; - # else - # ifdef FEAT_GUI_MSWIN -@@ -4275,7 +4290,7 @@ gui_update_scrollbars( - # endif - #endif - --#if defined(FEAT_GUI_TABLINE) && defined(FEAT_GUI_MSWIN) -+#if defined(FEAT_GUI_TABLINE) && (defined(FEAT_GUI_MSWIN) || defined(FEAT_GUI_HAIKU)) - if (gui_has_tabline()) - y += gui.tabline_height; - #endif -@@ -4994,7 +5009,8 @@ ex_gui(exarg_T *eap) - } - - #if ((defined(FEAT_GUI_X11) || defined(FEAT_GUI_GTK) \ -- || defined(FEAT_GUI_MSWIN) || defined(FEAT_GUI_PHOTON)) \ -+ || defined(FEAT_GUI_MSWIN) || defined(FEAT_GUI_PHOTON) \ -+ || defined(FEAT_GUI_HAIKU)) \ - && defined(FEAT_TOOLBAR)) || defined(PROTO) - /* - * This is shared between Athena, Motif and GTK. -diff --git a/src/gui.h b/src/gui.h -index a16f098..bd96e62 100644 ---- a/src/gui.h -+++ b/src/gui.h -@@ -29,6 +29,10 @@ - # include - #endif - -+#ifdef FEAT_GUI_HAIKU -+# include "gui_haiku.h" -+#endif -+ - #ifdef FEAT_GUI_MAC - # include - /*# include */ -@@ -66,7 +70,7 @@ - * GUIs that support dropping files on a running Vim. - */ - #if (defined(FEAT_DND) && defined(FEAT_GUI_GTK)) \ -- || defined(FEAT_GUI_MSWIN) \ -+ || defined(FEAT_GUI_MSWIN) || defined(FEAT_GUI_HAIKU) \ - || defined(FEAT_GUI_MAC) - # define HAVE_DROP_FILE - #endif -@@ -194,6 +198,9 @@ typedef struct GuiScrollbar - scroll_shift is set to the number of shifts - to reduce the count. */ - #endif -+#if FEAT_GUI_HAIKU -+ VimScrollBar *id; /* Pointer to real scroll bar */ -+#endif - #ifdef FEAT_GUI_MAC - ControlHandle id; /* A handle to the scrollbar */ - #endif -@@ -420,7 +427,7 @@ typedef struct Gui - - #if defined(FEAT_GUI_TABLINE) \ - && (defined(FEAT_GUI_MSWIN) || defined(FEAT_GUI_MOTIF) \ -- || defined(FEAT_GUI_MAC)) -+ || defined(FEAT_GUI_MAC) || defined(FEAT_GUI_HAIKU)) - int tabline_height; - #endif - -@@ -429,7 +436,7 @@ typedef struct Gui - #endif - - #if defined(FEAT_TOOLBAR) \ -- && (defined(FEAT_GUI_ATHENA) || defined(FEAT_GUI_MOTIF)) -+ && (defined(FEAT_GUI_ATHENA) || defined(FEAT_GUI_MOTIF) || defined(FEAT_GUI_HAIKU)) - int toolbar_height; /* height of the toolbar */ - #endif - -@@ -450,6 +457,14 @@ typedef struct Gui - guicolor_T currSpColor; /* Current special text color */ - #endif - -+#ifdef FEAT_GUI_HAIKU -+ 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 --git a/src/misc1.c b/src/misc1.c -index 3797094..972eb21 100644 ---- a/src/misc1.c -+++ b/src/misc1.c -@@ -18,6 +18,10 @@ - # include - #endif - -+#if defined(__HAIKU__) -+#include -+#endif -+ - static char_u *vim_version_dir(char_u *vimdir); - static char_u *remove_tail(char_u *p, char_u *pend, char_u *name); - -@@ -4343,7 +4347,16 @@ vim_getenv(char_u *name, int *mustfree) - // handling $VIMRUNTIME and $VIM is below, bail out if it's another name. - vimruntime = (STRCMP(name, "VIMRUNTIME") == 0); - if (!vimruntime && STRCMP(name, "VIM") != 0) -- return NULL; -+#if defined(__HAIKU__) -+ // special handling for user settings directory... -+ if(STRCMP(name, "BE_USER_SETTINGS") == 0) { -+ static char userSettingsPath[MAXPATHL] = {0}; -+ if(B_OK == find_directory(B_USER_SETTINGS_DIRECTORY, 0, -+ false, userSettingsPath, MAXPATHL)) -+ return userSettingsPath; -+ } else -+#endif -+ return NULL; - - /* - * When expanding $VIMRUNTIME fails, try using $VIM/vim or $VIM. -diff --git a/src/normal.c b/src/normal.c -index 06595e9..c992611 100644 ---- a/src/normal.c -+++ b/src/normal.c -@@ -2604,7 +2604,7 @@ do_mouse( - * menu on the button down event. */ - return FALSE; - # endif --# if defined(FEAT_GUI_ATHENA) || defined(FEAT_GUI_MSWIN) -+# if defined(FEAT_GUI_ATHENA) || defined(FEAT_GUI_MSWIN) || defined(FEAT_GUI_HAIKU) - if (is_click || is_drag) - /* Ignore right button down and drag mouse events. Windows - * only shows the popup menu on the button up event. */ -diff --git a/src/option.h b/src/option.h -index 37f6dca..ece0fbe 100644 ---- a/src/option.h -+++ b/src/option.h -@@ -10,6 +10,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 -@@ -1169,5 +1171,7 @@ enum - , WV_COUNT /* must be the last one */ - }; - -+#endif //_OPTION_H_ -+ - /* Value for b_p_ul indicating the global value must be used. */ - #define NO_LOCAL_UNDOLEVEL -123456 -diff --git a/src/os_unix.c b/src/os_unix.c -index 528089b..9d74096 100644 ---- a/src/os_unix.c -+++ b/src/os_unix.c -@@ -2126,7 +2126,7 @@ mch_settitle(char_u *title, char_u *icon) - if (get_x11_windis() == OK) - type = 1; - #else --# if defined(FEAT_GUI_PHOTON) || defined(FEAT_GUI_MAC) || defined(FEAT_GUI_GTK) -+# if defined(FEAT_GUI_PHOTON) || defined(FEAT_GUI_MAC) || defined(FEAT_GUI_GTK) || defined(FEAT_GUI_HAIKU) - if (gui.in_use) - type = 1; - # endif -@@ -2159,7 +2159,7 @@ mch_settitle(char_u *title, char_u *icon) - # endif - set_x11_title(title); /* x11 */ - #endif --#if defined(FEAT_GUI_GTK) \ -+#if defined(FEAT_GUI_GTK) || defined(FEAT_GUI_HAIKU)\ - || defined(FEAT_GUI_PHOTON) || defined(FEAT_GUI_MAC) - else - gui_mch_settitle(title, icon); -@@ -4559,7 +4559,7 @@ mch_call_shell_fork( - { - SIGSET_DECL(curset) - --# ifdef __BEOS__ -+# if defined(__BEOS__) && USE_THREAD_FOR_INPUT_WITH_TIMEOUT - beos_cleanup_read_thread(); - # endif - -diff --git a/src/os_unix.h b/src/os_unix.h -index 5df943c..2132969 100644 ---- a/src/os_unix.h -+++ b/src/os_unix.h -@@ -364,6 +364,8 @@ typedef struct dsc$descriptor DESC; - - #define DFLT_ERRORFILE "errors.err" - -+#ifndef DFLT_RUNTIMEPATH -+ - #ifdef VMS - # define DFLT_RUNTIMEPATH "sys$login:vimfiles,$VIM/vimfiles,$VIMRUNTIME,$VIM/vimfiles/after,sys$login:vimfiles/after" - # define CLEAN_RUNTIMEPATH "$VIM/vimfiles,$VIMRUNTIME,$VIM/vimfiles/after" -@@ -382,6 +384,8 @@ typedef struct dsc$descriptor DESC; - # endif - #endif - -+#endif -+ - #ifdef VMS - # ifndef VAX - # define VMS_TEMPNAM /* to fix default .LIS extension */ -diff --git a/src/osdef1.h.in b/src/osdef1.h.in -index 825fe94..4fb3409 100644 ---- a/src/osdef1.h.in -+++ b/src/osdef1.h.in -@@ -65,7 +65,7 @@ extern void memmove(char *, char *, int); - # endif - # endif - #endif --#ifndef __BIONIC__ // Android's libc #defines bzero to memset. -+#if !defined(__BIONIC__) && !defined(__HAIKU__) // Android's libc #defines bzero to memset. - // used inside of FD_ZERO macro - extern void bzero(void *, size_t); - #endif -diff --git a/src/proto.h b/src/proto.h -index e34af85..5c9a7a8 100644 ---- a/src/proto.h -+++ b/src/proto.h -@@ -310,6 +310,9 @@ extern char_u *vimpty_getenv(const char_u *string); /* in misc2.c */ - extern char *vim_SelFile(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_HAIKU -+# include "gui_haiku.pro" -+# endif - # ifdef FEAT_GUI_MAC - # include "gui_mac.pro" - # endif -diff --git a/src/pty.c b/src/pty.c -index 7a9e693..84cc976 100644 ---- a/src/pty.c -+++ b/src/pty.c -@@ -387,7 +387,7 @@ mch_openpty(char **ttyn) - 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 --git a/src/screen.c b/src/screen.c -index 862a635..08e65ef 100644 ---- a/src/screen.c -+++ b/src/screen.c -@@ -89,6 +89,15 @@ - - #include "vim.h" - -+#ifdef __HAIKU__ -+// FIXME!!! -+ int -+gui_mch_is_blink_off(void) -+{ -+ return FALSE; -+} -+#endif -+ - #define MB_FILLER_CHAR '<' /* character used when a double-width character - * doesn't fit. */ - -@@ -8731,6 +8740,10 @@ retry: - - win_new_shellsize(); /* fit the windows in the new sized shell */ - -+#ifdef FEAT_GUI_HAIKU -+ vim_lock_screen(); /* be safe, put it here */ -+#endif -+ - comp_col(); /* recompute columns for shown command and ruler */ - - /* -@@ -8932,6 +8945,10 @@ give_up: - #endif - clear_TabPageIdxs(); - -+#ifdef FEAT_GUI_HAIKU -+ vim_unlock_screen(); -+#endif -+ - entered = FALSE; - --RedrawingDisabled; - -@@ -9760,6 +9777,10 @@ screen_ins_lines( - clip_scroll_selection(-line_count); - #endif - -+#ifdef FEAT_GUI_HAIKU -+ vim_lock_screen(); -+#endif -+ - #ifdef FEAT_GUI - /* Don't update the GUI cursor here, ScreenLines[] is invalid until the - * scrolling is actually carried out. */ -@@ -9814,6 +9835,10 @@ screen_ins_lines( - } - } - -+#ifdef FEAT_GUI_HAIKU -+ vim_unlock_screen(); -+#endif -+ - screen_stop_highlight(); - windgoto(cursor_row, cursor_col); - if (clear_attr != 0) -@@ -9980,6 +10005,10 @@ screen_del_lines( - clip_scroll_selection(line_count); - #endif - -+#ifdef FEAT_GUI_HAIKU -+ vim_lock_screen(); -+#endif -+ - #ifdef FEAT_GUI - /* Don't update the GUI cursor here, ScreenLines[] is invalid until the - * scrolling is actually carried out. */ -@@ -10042,6 +10071,10 @@ screen_del_lines( - } - } - -+#ifdef FEAT_GUI_HAIKU -+ vim_unlock_screen(); -+#endif -+ - if (screen_attr != clear_attr) - screen_stop_highlight(); - if (clear_attr != 0) -diff --git a/src/structs.h b/src/structs.h -index c992e2a..550f189 100644 ---- a/src/structs.h -+++ b/src/structs.h -@@ -3258,6 +3258,13 @@ struct VimMenu - HMENU submenu_id; /* If this is submenu, add children here */ - HWND tearoff_handle; /* hWnd of tearoff if created */ - #endif -+#if FEAT_GUI_HAIKU -+ BMenuItem *id; /* Id of menu item */ -+ BMenu *submenu_id; /* If this is submenu, add children here */ -+# ifdef FEAT_TOOLBAR -+ BPictureButton *button; -+# endif -+#endif - #ifdef FEAT_GUI_MAC - /* MenuHandle id; */ - /* short index; */ /* the item index within the father menu */ -diff --git a/src/term.c b/src/term.c -index af7d27c..48adf20 100644 ---- a/src/term.c -+++ b/src/term.c -@@ -1399,6 +1399,11 @@ termgui_mch_get_rgb(guicolor_T color) - # 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 --git a/src/ui.c b/src/ui.c -index 972880d..0ae8214 100644 ---- a/src/ui.c -+++ b/src/ui.c -@@ -3391,7 +3391,7 @@ mouse_find_win(int *rowp, int *colp UNUSED) - } - - #if defined(FEAT_GUI_MOTIF) || defined(FEAT_GUI_GTK) || defined(FEAT_GUI_MAC) \ -- || defined(FEAT_GUI_ATHENA) || defined(FEAT_GUI_MSWIN) \ -+ || defined(FEAT_GUI_ATHENA) || defined(FEAT_GUI_MSWIN) || defined(FEAT_GUI_HAIKU) \ - || defined(FEAT_GUI_PHOTON) || defined(FEAT_TERM_POPUP_MENU) \ - || defined(PROTO) - /* -diff --git a/src/version.c b/src/version.c -index 5c6e506..11c2590 100644 ---- a/src/version.c -+++ b/src/version.c -@@ -3591,6 +3591,9 @@ list_version(void) - msg_puts(_("with X11-Athena GUI.")); - # endif - # else -+# ifdef FEAT_GUI_HAIKU -+ MSG_PUTS(_("with Haiku GUI.")); -+# else - # ifdef FEAT_GUI_PHOTON - msg_puts(_("with Photon GUI.")); - # else -@@ -3605,6 +3608,7 @@ list_version(void) - # else - # endif - # endif -+# endif - # endif - # endif - # endif -diff --git a/src/vim.h b/src/vim.h -index 2c9149b..ff373f4 100644 ---- a/src/vim.h -+++ b/src/vim.h -@@ -111,6 +111,7 @@ - #if defined(FEAT_GUI_MOTIF) \ - || defined(FEAT_GUI_GTK) \ - || defined(FEAT_GUI_ATHENA) \ -+ || defined(FEAT_GUI_HAIKU) \ - || defined(FEAT_GUI_MAC) \ - || defined(FEAT_GUI_MSWIN) \ - || defined(FEAT_GUI_PHOTON) -@@ -240,6 +241,11 @@ - # include "os_beos.h" - #endif - -+#ifdef __HAIKU__ -+# include "os_haiku.h" -+# define __ARGS(x) x -+#endif -+ - #if (defined(UNIX) || defined(VMS)) \ - && (!defined(MACOS_X) || defined(HAVE_CONFIG_H)) - # include "os_unix.h" /* bring lots of system header files */ -@@ -2038,6 +2044,9 @@ typedef struct VimClipboard - int_u format; /* Vim's own special clipboard format */ - int_u format_raw; /* Vim's raw text clipboard format */ - # endif -+# ifdef FEAT_GUI_HAIKU -+ /* no clipboard at the moment. TODO???? */ -+# endif - } VimClipboard; - #else - typedef int VimClipboard; /* This is required for the prototypes. */ -@@ -2088,7 +2097,7 @@ typedef enum { - * functions of these names. The declarations would break if the defines had - * been seen at that stage. But it must be before globals.h, where error_ga - * is declared. */ --#if !defined(MSWIN) && !defined(FEAT_GUI_X11) \ -+#if !defined(MSWIN) && !defined(FEAT_GUI_X11) && !defined(FEAT_GUI_HAIKU) \ - && !defined(FEAT_GUI_GTK) && !defined(FEAT_GUI_MAC) && !defined(PROTO) - # define mch_errmsg(str) fprintf(stderr, "%s", (str)) - # define display_errors() fflush(stderr) --- -2.21.0 - - -From cd0e20149f7e9cb87b8239389c042e705154f8cf Mon Sep 17 00:00:00 2001 -From: Adrien Destugues -Date: Wed, 1 May 2019 12:12:41 +0200 -Subject: Fix build for vim 8.1 - - -diff --git a/src/evalfunc.c b/src/evalfunc.c -index 0346fc7..ff4ae39 100644 ---- a/src/evalfunc.c -+++ b/src/evalfunc.c -@@ -9235,8 +9235,9 @@ f_readdir(typval_T *argvars, typval_T *rettv) - char_u *path; - garray_T ga; - int i; -+ char_u *p; - #ifdef MSWIN -- char_u *buf, *p; -+ char_u *buf; - int ok; - HANDLE hFind = INVALID_HANDLE_VALUE; - WIN32_FIND_DATAW wfb; -@@ -9311,9 +9312,9 @@ f_readdir(typval_T *argvars, typval_T *rettv) - vim_free(buf); - vim_free(wn); - #else -+ { - DIR *dirp; - struct dirent *dp; -- char_u *p; - - dirp = opendir((char *)path); - if (dirp == NULL) -@@ -9356,6 +9357,7 @@ f_readdir(typval_T *argvars, typval_T *rettv) - - closedir(dirp); - } -+ } - #endif - - if (!failed && rettv->vval.v_list != NULL && ga.ga_len > 0) -diff --git a/src/fileio.c b/src/fileio.c -index 659878e..3607cb5 100644 ---- a/src/fileio.c -+++ b/src/fileio.c -@@ -6131,6 +6131,7 @@ shorten_fnames(int force) - - #if (defined(FEAT_DND) && defined(FEAT_GUI_GTK)) \ - || defined(FEAT_GUI_MSWIN) \ -+ || defined(FEAT_GUI_HAIKU) \ - || defined(FEAT_GUI_MAC) \ - || defined(PROTO) - /* -diff --git a/src/globals.h b/src/globals.h -index fef30a7..72e8781 100644 ---- a/src/globals.h -+++ b/src/globals.h -@@ -1393,7 +1393,7 @@ EXTERN char e_failed[] INIT(= N_("E472: Command failed")); - EXTERN char e_fontset[] INIT(= N_("E234: Unknown fontset: %s")); - #endif - #if defined(FEAT_GUI_X11) || defined(FEAT_GUI_GTK) || defined(FEAT_GUI_MAC) \ -- || defined(FEAT_GUI_PHOTON) || defined(FEAT_GUI_MSWIN) -+ || defined(FEAT_GUI_HAIKU) || defined(FEAT_GUI_PHOTON) || defined(FEAT_GUI_MSWIN) - EXTERN char e_font[] INIT(= N_("E235: Unknown font: %s")); - #endif - #if defined(FEAT_GUI_X11) && !defined(FEAT_GUI_GTK) -diff --git a/src/gui_haiku.cc b/src/gui_haiku.cc -index ef0ec7d..0389d92 100644 ---- a/src/gui_haiku.cc -+++ b/src/gui_haiku.cc -@@ -488,9 +488,7 @@ struct MainArgs { - struct VimKeyMsg { - char_u length; - char_u chars[KEY_MSG_BUFSIZ]; /* contains Vim encoding */ --#ifdef FEAT_MBYTE - bool csi_escape; --#endif - }; - - struct VimResizeMsg { -@@ -660,6 +658,15 @@ docd(BPath &path) - do_cmdline_cmd((char_u *)"cd ."); - } - -+ static void -+drop_callback(void *cookie) -+{ -+ /* TODO here we could handle going to a specific position in the dropped -+ * file (see src/gui_mac.c) */ -+ /* Update the screen display */ -+ update_screen(NOT_VALID); -+} -+ - /* - * Really handle dropped files and folders. - */ -@@ -763,10 +770,8 @@ bad: - - /* Handle the drop, :edit to get to the file */ - if (fname_index > 0) { -- handle_drop(fname_index, fnames, FALSE); -+ handle_drop(fname_index, fnames, FALSE, drop_callback, NULL); - -- /* Update the screen display */ -- update_screen(NOT_VALID); - setcursor(); - out_flush(); - } else { -@@ -976,9 +981,7 @@ VimWindow::QuitRequested() - 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)); - -@@ -1259,9 +1262,7 @@ VimTextAreaView::KeyDown(const char *bytes, int32 numBytes) - 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); -@@ -1398,9 +1399,7 @@ notspecial: - } - 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)); -@@ -1704,15 +1703,11 @@ VimTextAreaView::mchDrawString(int row, int col, char_u *s, int len, int flags) - */ - if (!(flags & DRAW_TRANSP)) { - int cells; --#ifdef FEAT_MBYTE - cells = 0; - for(int i=0; iname); -+ semsg(_(e_font), font->name); - delete font; - return NOFONT; - } -@@ -4309,6 +4290,12 @@ gui_mch_draw_string( - } - } - -+ guicolor_T -+gui_mch_get_rgb_color(int r, int g, int b) -+{ -+ return gui_get_rgb_color_cmn(r, g, b); -+} -+ - /* - * Return OK if the key with the termcap name "name" is supported. - */ -@@ -4391,7 +4378,7 @@ gui_mch_iconify() - * Bring the Vim window to the foreground. - */ - void --gui_mch_set_foreground() -+gui_mch_set_foreground(void) - { - /* TODO */ - } -@@ -4422,13 +4409,9 @@ gui_mch_draw_hollow_cursor(guicolor_T 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()) { -@@ -5143,26 +5126,6 @@ im_set_position(int row, int col) - } - 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 - - void -diff --git a/src/mbyte.c b/src/mbyte.c -index 411c3d9..b88a7b5 100644 ---- a/src/mbyte.c -+++ b/src/mbyte.c -@@ -6479,7 +6479,7 @@ im_set_active(int active_arg) - # endif - } - --# ifdef FEAT_GUI -+# if defined(FEAT_GUI) && !defined(FEAT_GUI_HAIKU) - void - im_set_position(int row UNUSED, int col UNUSED) - { -diff --git a/src/proto/gui_haiku.pro b/src/proto/gui_haiku.pro -index deb412b..cd3e4a3 100644 ---- a/src/proto/gui_haiku.pro -+++ b/src/proto/gui_haiku.pro -@@ -12,6 +12,7 @@ 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_rgb(guicolor_T pixel); -+guicolor_T gui_mch_get_rgb_color(int r, int g, int b); - guicolor_T gui_mch_get_color __ARGS((char_u *name)); - - GuiFont gui_mch_get_font __ARGS((char_u *name, int giveErrorIfMissing)); -@@ -43,7 +44,7 @@ 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_set_foreground(void); - 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)); -diff --git a/src/version.c b/src/version.c -index 11c2590..92debef 100644 ---- a/src/version.c -+++ b/src/version.c -@@ -3592,7 +3592,7 @@ list_version(void) - # endif - # else - # ifdef FEAT_GUI_HAIKU -- MSG_PUTS(_("with Haiku GUI.")); -+ msg_puts(_("with Haiku GUI.")); - # else - # ifdef FEAT_GUI_PHOTON - msg_puts(_("with Photon GUI.")); --- -2.21.0 - diff --git a/app-editors/vim/vim-8.1.1240.recipe b/app-editors/vim/vim-8.2.0647.recipe similarity index 56% rename from app-editors/vim/vim-8.1.1240.recipe rename to app-editors/vim/vim-8.2.0647.recipe index f329e8f61..a8573c3cd 100644 --- a/app-editors/vim/vim-8.1.1240.recipe +++ b/app-editors/vim/vim-8.2.0647.recipe @@ -10,72 +10,78 @@ configuration files. Despite this, Vim can be configured to work in a very simple (Notepad-like) \ way, called evim or Easy Vim." HOMEPAGE="https://www.vim.org/" -COPYRIGHT="1991-2019 Bram Moleenar et al." +COPYRIGHT="1991-2020 Bram Moleenar et al." LICENSE="Vim" -REVISION="4" +REVISION="1" SOURCE_URI="https://github.com/vim/vim/archive/v$portVersion.tar.gz" -CHECKSUM_SHA256="3bfb6b0de36e96862933e49df93412a46a0914356ec16dd60a5ccbd5cdc46d25" +CHECKSUM_SHA256="2528387233967e7e8cdcd28eedca290959b48d7cb471fd1aa6ea5edfc51f279c" SOURCE_FILENAME="vim-$portVersion.tar.gz" -PATCHES="vim-$portVersion.patchset" -ARCHITECTURES="x86_gcc2 ?x86 x86_64" +ARCHITECTURES="!x86_gcc2 x86_64" +SECONDARY_ARCHITECTURES="x86" + +commandSuffix=$secondaryArchSuffix +commandBinDir=$binDir +if [ "$targetArchitecture" = x86_gcc2 ]; then + commandSuffix= + commandBinDir=$prefix/bin +fi PROVIDES=" vim = $portVersion - cmd:ex = $portVersion - cmd:gview = $portVersion - cmd:gvim = $portVersion - cmd:gvimdiff = $portVersion - cmd:rgview = $portVersion - cmd:rgvim = $portVersion - cmd:rview = $portVersion - cmd:rvim = $portVersion - cmd:vi = $portVersion - cmd:view = $portVersion - cmd:vim = $portVersion compat >= 8.1 - cmd:vimdiff = $portVersion - cmd:vimtutor = $portVersion - cmd:xxd = $portVersion + cmd:ex$commandSuffix = $portVersion + cmd:gview$commandSuffix = $portVersion + cmd:gvim$commandSuffix = $portVersion + cmd:gvimdiff$commandSuffix = $portVersion + cmd:rgview$commandSuffix = $portVersion + cmd:rgvim$commandSuffix = $portVersion + cmd:rview$commandSuffix = $portVersion + cmd:rvim$commandSuffix = $portVersion + cmd:vi$commandSuffix = $portVersion + cmd:view$commandSuffix = $portVersion + cmd:vim$commandSuffix = $portVersion compat >= 8.1 + cmd:vimdiff$commandSuffix = $portVersion + cmd:vimtutor$commandSuffix = $portVersion + cmd:xxd$commandSuffix = $portVersion " REQUIRES=" - haiku - lib:libiconv - lib:libintl - lib:libncurses >= 6 + haiku$secondaryArchSuffix + lib:libiconv$secondaryArchSuffix + lib:libintl$secondaryArchSuffix + lib:libncurses$secondaryArchSuffix >= 6 " if [ $effectiveTargetArchitecture != "x86_gcc2" ] ; then REQUIRES+=" - lib:libssp + lib:libssp$secondaryArchSuffix " fi BUILD_REQUIRES=" - haiku_devel - devel:libiconv - devel:libintl -# devel:liblua - devel:libncurses >= 6 + haiku${secondaryArchSuffix}_devel + devel:libiconv$secondaryArchSuffix + devel:libintl$secondaryArchSuffix +# devel:liblua$secondaryArchSuffix + devel:libncurses$secondaryArchSuffix >= 6 devel:libtclstub8.5 -" + " if [ $effectiveTargetArchitecture != "x86_gcc2" ] ; then BUILD_REQUIRES+=" - devel:libruby + devel:libruby$secondaryArchSuffix " fi BUILD_PREREQUIRES=" cmd:autoconf cmd:find - cmd:gcc + cmd:gcc$secondaryArchSuffix cmd:gettext cmd:grep cmd:make # cmd:perl cmd:pkg_config$secondaryArchSuffix - cmd:python2 -# cmd:python3 + cmd:python3 cmd:ruby cmd:sed " @@ -89,7 +95,7 @@ BUILD() autoconf export CFLAGS="\ - `pkg-config --cflags python2` \ + `pkg-config --cflags python3` \ -fPIC" # CLI ------------------------------------------- @@ -97,21 +103,20 @@ BUILD() # Clean objects from possible previous run to avoid mixup of GUI/CLI objects rm objects/*.o || true - runConfigure ./configure \ + runConfigure --omit-dirs binDir ./configure \ + --bindir="$commandBinDir" \ --disable-gui \ - --with-features=big \ + --with-features=huge \ --enable-cscope \ - --enable-multibyte \ --enable-pythoninterp=dynamic \ --enable-rubyinterp=dynamic \ --enable-tclinterp=dynamic \ - --enable-terminal \ - --with-compiledby=Haikuports + --with-compiledby=Haikuports \ + --disable-terminal # FIXME: 'exit' command does not work # --enable-luainterp=dynamic # --enable-python3interp=dynamic currently broken # --enable-perlinterp=dynamic not dynamic yet - make $jobArgs cp vim vim.con # preserve gui-less executable rm objects/*.o @@ -125,15 +130,15 @@ BUILD() sed -i "s|@MIDDLE@|$MIDDLE|" os_haiku.rdef sed -i "s|@MINOR@|$MINOR|" os_haiku.rdef - runConfigure ./configure \ - --with-features=big \ + runConfigure --omit-dirs binDir ./configure \ + --bindir="$commandBinDir" \ + --with-features=huge \ --enable-cscope \ - --enable-multibyte \ --enable-pythoninterp=dynamic \ --enable-rubyinterp=dynamic \ --enable-tclinterp==dynamic \ - --with-compiledby=Haikuports -# --enable-terminal # FIXME builds, but does not display anything + --with-compiledby=Haikuports \ + --disable-terminal # FIXME: Builds, but does not display anything # --enable-luainterp=dynamic # --enable-python3interp=dynamic currently broken # --enable-perlinterp=dynamic not dynamic yet @@ -144,15 +149,8 @@ BUILD() INSTALL() { make install - - cat << EOF > $dataDir/vim/vimrc -" Workaround to get the themes and plugins work -execute "set runtimepath+=" . substitute(system("finddir B_USER_SETTINGS_DIRECTORY"), '\n\+$', '', '') . "/vim" -EOF - - ln -s vim $binDir/vi - - addAppDeskbarSymlink $binDir/gvim Vim + ln -s vim $commandBinDir/vi + addAppDeskbarSymlink $commandBinDir/gvim Vim } TEST()