diff options
-rw-r--r-- | Makefile | 4 | ||||
-rw-r--r-- | cmdline.cpp | 27 | ||||
-rw-r--r-- | interface-gtk.cpp | 196 | ||||
-rw-r--r-- | interface-gtk.h | 60 | ||||
-rw-r--r-- | interface.h | 54 | ||||
-rw-r--r-- | main.cpp | 187 | ||||
-rw-r--r-- | parser.cpp | 114 | ||||
-rw-r--r-- | parser.h | 3 | ||||
-rw-r--r-- | qbuffers.cpp | 90 | ||||
-rw-r--r-- | sciteco.h | 21 | ||||
-rw-r--r-- | undo.cpp | 3 |
11 files changed, 452 insertions, 307 deletions
@@ -6,7 +6,7 @@ GTK_LDFLAGS:=$(shell pkg-config --libs gtk+-2.0) SCI_CFLAGS:=-I../scintilla/include -DGTK -DSCI_LEXER SCI_LDFLAGS:=../scintilla/bin/scintilla.a -CPPFLAGS:= +CPPFLAGS:=-DINTERFACE_GTK CFLAGS:=-Wall -std=c99 -g -O0 $(GTK_CFLAGS) $(SCI_CFLAGS) CXXFLAGS:=-Wall -g -O0 $(GTK_CFLAGS) $(SCI_CFLAGS) LDFLAGS:=$(GTK_LDFLAGS) $(SCI_LDFLAGS) @@ -15,7 +15,7 @@ all : sciteco sciteco : main.o cmdline.o undo.o expressions.o qbuffers.o \ parser.o goto.o rbtree.o \ - gtk-info-popup.o + interface-gtk.o gtk-info-popup.o $(CXX) -o $@ $^ $(LDFLAGS) main.o : gtk-info-popup.h diff --git a/cmdline.cpp b/cmdline.cpp index db1d1ef..557e056 100644 --- a/cmdline.cpp +++ b/cmdline.cpp @@ -6,6 +6,7 @@ #include <glib/gstdio.h> #include "sciteco.h" +#include "interface.h" #include "parser.h" #include "qbuffers.h" #include "goto.h" @@ -33,10 +34,7 @@ cmdline_keypress(gchar key) /* * Cleanup messages, popups, etc... */ - if (gtk_widget_get_visible(GTK_WIDGET(filename_popup))) { - gtk_widget_hide(GTK_WIDGET(filename_popup)); - gtk_info_popup_clear(filename_popup); - } + interface.popup_clear(); /* * Process immediate editing commands @@ -68,7 +66,7 @@ cmdline_keypress(gchar key) * Echo command line */ echo = macro_echo(cmdline, "*"); - cmdline_display(echo); + interface.cmdline_update(echo); g_free(echo); } @@ -231,23 +229,22 @@ filename_complete(const gchar *filename, gchar completed) for (GList *file = g_list_first(matching); file != NULL; file = g_list_next(file)) { - GtkInfoPopupFileType type; - gboolean in_buffer = FALSE; + Interface::PopupFileType type; + bool in_buffer = false; if (filename_is_dir((gchar *)file->data)) { - type = GTK_INFO_POPUP_DIRECTORY; + type = Interface::POPUP_DIRECTORY; } else { - type = GTK_INFO_POPUP_FILE; + type = Interface::POPUP_FILE; /* FIXME: inefficient */ - in_buffer = ring.find((gchar *)file->data) - != NULL; + in_buffer = ring.find((gchar *)file->data); } - gtk_info_popup_add_filename(filename_popup, - type, (gchar *)file->data, - in_buffer); + + interface.popup_add_filename(type, (gchar *)file->data, + in_buffer); } - gtk_widget_show(GTK_WIDGET(filename_popup)); + interface.popup_show(); } else if (g_list_length(matching) == 1 && !filename_is_dir((gchar *)g_list_first(matching)->data)) { gchar *new_insert; diff --git a/interface-gtk.cpp b/interface-gtk.cpp new file mode 100644 index 0000000..55e546e --- /dev/null +++ b/interface-gtk.cpp @@ -0,0 +1,196 @@ +#include <stdarg.h> + +#include <glib.h> +#include <glib/gprintf.h> +#include <glib/gstdio.h> + +#include <gdk/gdk.h> +#include <gdk/gdkkeysyms.h> + +#include <gtk/gtk.h> +#include "gtk-info-popup.h" + +#include <Scintilla.h> +#include <ScintillaWidget.h> + +#include "sciteco.h" +#include "interface.h" +#include "interface-gtk.h" + +InterfaceGtk interface; + +extern "C" { +static gboolean cmdline_key_pressed(GtkWidget *widget, GdkEventKey *event, + gpointer user_data); +static gboolean exit_app(GtkWidget *w, GdkEventAny *e, gpointer p); +} + +InterfaceGtk::InterfaceGtk() +{ + GtkWidget *window, *vbox; + GtkWidget *info_content; + + gtk_init(NULL, NULL); + + window = gtk_window_new(GTK_WINDOW_TOPLEVEL); + gtk_window_set_title(GTK_WINDOW(window), "SciTECO"); + g_signal_connect(G_OBJECT(window), "delete-event", + G_CALLBACK(exit_app), NULL); + + vbox = gtk_vbox_new(FALSE, 0); + + editor_widget = scintilla_new(); + scintilla_set_id(SCINTILLA(editor_widget), 0); + gtk_widget_set_usize(editor_widget, 500, 300); + gtk_widget_set_can_focus(editor_widget, FALSE); + gtk_box_pack_start(GTK_BOX(vbox), editor_widget, TRUE, TRUE, 0); + + info_widget = gtk_info_bar_new(); + info_content = gtk_info_bar_get_content_area(GTK_INFO_BAR(info_widget)); + message_widget = gtk_label_new(""); + gtk_misc_set_alignment(GTK_MISC(message_widget), 0., 0.); + gtk_container_add(GTK_CONTAINER(info_content), message_widget); + gtk_box_pack_start(GTK_BOX(vbox), info_widget, FALSE, FALSE, 0); + + cmdline_widget = gtk_entry_new(); + gtk_entry_set_has_frame(GTK_ENTRY(cmdline_widget), FALSE); + gtk_editable_set_editable(GTK_EDITABLE(cmdline_widget), FALSE); + widget_set_font(cmdline_widget, "Courier"); + g_signal_connect(G_OBJECT(cmdline_widget), "key-press-event", + G_CALLBACK(cmdline_key_pressed), NULL); + gtk_box_pack_start(GTK_BOX(vbox), cmdline_widget, FALSE, FALSE, 0); + + gtk_container_add(GTK_CONTAINER(window), vbox); + + popup_widget = gtk_info_popup_new(cmdline_widget); + + gtk_widget_grab_focus(cmdline_widget); + gtk_widget_show_all(window); +} + +void +InterfaceGtk::msg(MessageType type, const gchar *fmt, ...) +{ + static const GtkMessageType type2gtk[] = { + /* [MSG_USER] = */ GTK_MESSAGE_OTHER, + /* [MSG_INFO] = */ GTK_MESSAGE_INFO, + /* [MSG_WARNING] = */ GTK_MESSAGE_WARNING, + /* [MSG_ERROR] = */ GTK_MESSAGE_ERROR + }; + + va_list ap; + gchar buf[255]; + + va_start(ap, fmt); + g_vsnprintf(buf, sizeof(buf), fmt, ap); + va_end(ap); + + switch (type) { + case MSG_USER: + g_printf("%s\n", buf); + break; + case MSG_INFO: + g_printf("Info: %s\n", buf); + break; + case MSG_WARNING: + g_fprintf(stderr, "Warning: %s\n", buf); + break; + case MSG_ERROR: + g_fprintf(stderr, "Error: %s\n", buf); + break; + } + + gtk_info_bar_set_message_type(GTK_INFO_BAR(info_widget), + type2gtk[type]); + gtk_label_set_text(GTK_LABEL(message_widget), buf); +} + +void +InterfaceGtk::cmdline_update(const gchar *cmdline_str) +{ + gtk_entry_set_text(GTK_ENTRY(cmdline_widget), cmdline_str); + gtk_editable_set_position(GTK_EDITABLE(cmdline_widget), -1); +} + +void +InterfaceGtk::popup_add_filename(PopupFileType type, + const gchar *filename, bool highlight) +{ + static const GtkInfoPopupFileType type2gtk[] = { + /* [POPUP_FILE] = */ GTK_INFO_POPUP_FILE, + /* [POPUP_DIRECTORY] = */ GTK_INFO_POPUP_DIRECTORY + }; + + gtk_info_popup_add_filename(GTK_INFO_POPUP(popup_widget), + type2gtk[type], filename, highlight); +} + +void +InterfaceGtk::popup_clear(void) +{ + if (gtk_widget_get_visible(popup_widget)) { + gtk_widget_hide(popup_widget); + gtk_info_popup_clear(GTK_INFO_POPUP(popup_widget)); + } +} + +void +InterfaceGtk::widget_set_font(GtkWidget *widget, const gchar *font_name) +{ + PangoFontDescription *font_desc; + + font_desc = pango_font_description_from_string(font_name); + gtk_widget_modify_font(widget, font_desc); + pango_font_description_free(font_desc); +} + +/* + * GTK+ callbacks + */ + +static gboolean +cmdline_key_pressed(GtkWidget *widget, GdkEventKey *event, + gpointer user_data __attribute__((unused))) +{ +#ifdef DEBUG + g_printf("KEY \"%s\" (%d) SHIFT=%d CNTRL=%d\n", + event->string, *event->string, + event->state & GDK_SHIFT_MASK, event->state & GDK_CONTROL_MASK); +#endif + + switch (event->keyval) { + case GDK_BackSpace: + cmdline_keypress('\b'); + break; + case GDK_Tab: + cmdline_keypress('\t'); + break; + case GDK_Return: + switch (interface.ssm(SCI_GETEOLMODE)) { + case SC_EOL_CR: + cmdline_keypress('\r'); + break; + case SC_EOL_CRLF: + cmdline_keypress('\r'); + /* fall through */ + case SC_EOL_LF: + default: + cmdline_keypress('\n'); + } + break; + default: + if (*event->string) + cmdline_keypress(*event->string); + } + + return TRUE; +} + +static gboolean +exit_app(GtkWidget *w __attribute__((unused)), + GdkEventAny *e __attribute__((unused)), + gpointer p __attribute__((unused))) +{ + gtk_main_quit(); + return TRUE; +} diff --git a/interface-gtk.h b/interface-gtk.h new file mode 100644 index 0000000..76868fd --- /dev/null +++ b/interface-gtk.h @@ -0,0 +1,60 @@ +#ifndef __INTERFACE_GTK_H +#define __INTERFACE_GTK_H + +#include <glib.h> +#include <gtk/gtk.h> + +#include <Scintilla.h> +#include <ScintillaWidget.h> + +#include "interface.h" + +extern class InterfaceGtk : public Interface { + GtkWidget *editor_widget; + GtkWidget *cmdline_widget; + GtkWidget *info_widget, *message_widget; + + GtkWidget *popup_widget; + +public: + InterfaceGtk(); + //~InterfaceGtk(); + + inline void + parse_args(int &argc, char **&argv) + { + gtk_parse_args(&argc, &argv); + } + + void msg(MessageType type, const gchar *fmt, ...) G_GNUC_PRINTF(3, 4); + + inline sptr_t + ssm(unsigned int iMessage, uptr_t wParam = 0, sptr_t lParam = 0) + { + return scintilla_send_message(SCINTILLA(editor_widget), + iMessage, wParam, lParam); + } + + void cmdline_update(const gchar *cmdline); + + void popup_add_filename(PopupFileType type, + const gchar *filename, bool highlight = false); + inline void + popup_show(void) + { + gtk_widget_show(popup_widget); + } + void popup_clear(void); + + /* main entry point */ + inline void + event_loop(void) + { + gtk_main(); + } + +private: + static void widget_set_font(GtkWidget *widget, const gchar *font_name); +} interface; + +#endif diff --git a/interface.h b/interface.h new file mode 100644 index 0000000..a67fbfa --- /dev/null +++ b/interface.h @@ -0,0 +1,54 @@ +#ifndef __INTERFACE_H +#define __INTERFACE_H + +#include <glib.h> + +#include <Scintilla.h> + +/* + * Base class for all user interfaces - used mereley as a class interface. + * The actual instance of the interface has the platform-specific type + * (e.g. InterfaceGtk) since we would like to have the benefits of using + * classes but avoid the calling overhead when invoking virtual methods + * on Interface pointers. + * There's only one Interface* instance in the system. + */ +class Interface { +public: + virtual void parse_args(int &argc, char **&argv) {} + + enum MessageType { + MSG_USER, + MSG_INFO, + MSG_WARNING, + MSG_ERROR + }; + virtual void msg(MessageType type, const gchar *fmt, ...) + G_GNUC_PRINTF(3, 4) = 0; + + virtual sptr_t ssm(unsigned int iMessage, + uptr_t wParam = 0, sptr_t lParam = 0) = 0; + + virtual void cmdline_update(const gchar *cmdline) = 0; + + enum PopupFileType { + POPUP_FILE, + POPUP_DIRECTORY + }; + virtual void popup_add_filename(PopupFileType type, + const gchar *filename, + bool highlight = false) = 0; + virtual void popup_show(void) = 0; + virtual void popup_clear(void) = 0; + + /* main entry point */ + virtual void event_loop(void) = 0; +}; + +#ifdef INTERFACE_GTK +#include "interface-gtk.h" +#elif defined(INTERFACE_NCURSES) +#include "interface-ncurses.h" +#endif + +#endif @@ -1,134 +1,22 @@ #include <stdio.h> #include <string.h> -#include <stdarg.h> #include <stdlib.h> #include <glib.h> #include <glib/gprintf.h> #include <glib/gstdio.h> -#include <gdk/gdk.h> -#include <gdk/gdkkeysyms.h> - -#include <gtk/gtk.h> -#include "gtk-info-popup.h" - #include <Scintilla.h> #include <SciLexer.h> -#include <ScintillaWidget.h> #include "sciteco.h" +#include "interface.h" #include "parser.h" #include "qbuffers.h" #include "undo.h" -static GtkWidget *editor_widget; -static GtkWidget *cmdline_widget; -static GtkWidget *info_widget, *message_widget; - -GtkInfoPopup *filename_popup; - #define INI_FILE ".teco_ini" -void -cmdline_display(const gchar *cmdline_str) -{ - gtk_entry_set_text(GTK_ENTRY(cmdline_widget), cmdline_str); - gtk_editable_set_position(GTK_EDITABLE(cmdline_widget), -1); -} - -void -message_display(GtkMessageType type, const gchar *fmt, ...) -{ - va_list ap; - gchar buf[255]; - - va_start(ap, fmt); - g_vsnprintf(buf, sizeof(buf), fmt, ap); - va_end(ap); - - switch (type) { - case GTK_MESSAGE_ERROR: - g_fprintf(stderr, "Error: %s\n", buf); - break; - case GTK_MESSAGE_WARNING: - g_fprintf(stderr, "Warning: %s\n", buf); - break; - case GTK_MESSAGE_INFO: - g_printf("Info: %s\n", buf); - break; - default: - g_printf("%s\n", buf); - } - - gtk_info_bar_set_message_type(GTK_INFO_BAR(info_widget), type); - gtk_label_set_text(GTK_LABEL(message_widget), buf); -} - -sptr_t -editor_msg(unsigned int iMessage, uptr_t wParam, sptr_t lParam) -{ - return scintilla_send_message(SCINTILLA(editor_widget), - iMessage, wParam, lParam); -} - -static gboolean -cmdline_key_pressed(GtkWidget *widget, GdkEventKey *event, - gpointer user_data __attribute__((unused))) -{ -#ifdef DEBUG - g_printf("KEY \"%s\" (%d) SHIFT=%d CNTRL=%d\n", - event->string, *event->string, - event->state & GDK_SHIFT_MASK, event->state & GDK_CONTROL_MASK); -#endif - - switch (event->keyval) { - case GDK_BackSpace: - cmdline_keypress('\b'); - break; - case GDK_Tab: - cmdline_keypress('\t'); - break; - case GDK_Return: - switch (editor_msg(SCI_GETEOLMODE)) { - case SC_EOL_CR: - cmdline_keypress('\r'); - break; - case SC_EOL_CRLF: - cmdline_keypress('\r'); - /* fall through */ - case SC_EOL_LF: - default: - cmdline_keypress('\n'); - } - break; - default: - if (*event->string) - cmdline_keypress(*event->string); - } - - return TRUE; -} - -static gboolean -exit_app(GtkWidget *w __attribute__((unused)), - GdkEventAny *e __attribute__((unused)), - gpointer p __attribute__((unused))) -{ - gtk_main_quit(); - return TRUE; -} - -static void -widget_set_font(GtkWidget *widget, const gchar *font_name) -{ - PangoFontDescription *font_desc; - - font_desc = pango_font_description_from_string(font_name); - gtk_widget_modify_font(widget, font_desc); - pango_font_description_free(font_desc); -} - static gchar *mung_file = NULL; static inline void @@ -162,7 +50,7 @@ process_options(int &argc, char **&argv) INI_FILE, NULL); } - gtk_init(&argc, &argv); + interface.parse_args(argc, argv); /* remaining arguments, are arguments to the munged file */ } @@ -170,65 +58,30 @@ process_options(int &argc, char **&argv) int main(int argc, char **argv) { - GtkWidget *window, *vbox; - GtkWidget *info_content; - process_options(argc, argv); - window = gtk_window_new(GTK_WINDOW_TOPLEVEL); - gtk_window_set_title(GTK_WINDOW(window), "SciTECO"); - g_signal_connect(G_OBJECT(window), "delete-event", - G_CALLBACK(exit_app), NULL); - - vbox = gtk_vbox_new(FALSE, 0); - - editor_widget = scintilla_new(); - scintilla_set_id(SCINTILLA(editor_widget), 0); - gtk_widget_set_usize(editor_widget, 500, 300); - gtk_widget_set_can_focus(editor_widget, FALSE); - gtk_box_pack_start(GTK_BOX(vbox), editor_widget, TRUE, TRUE, 0); - - info_widget = gtk_info_bar_new(); - info_content = gtk_info_bar_get_content_area(GTK_INFO_BAR(info_widget)); - message_widget = gtk_label_new(""); - gtk_misc_set_alignment(GTK_MISC(message_widget), 0., 0.); - gtk_container_add(GTK_CONTAINER(info_content), message_widget); - gtk_box_pack_start(GTK_BOX(vbox), info_widget, FALSE, FALSE, 0); - - cmdline_widget = gtk_entry_new(); - gtk_entry_set_has_frame(GTK_ENTRY(cmdline_widget), FALSE); - gtk_editable_set_editable(GTK_EDITABLE(cmdline_widget), FALSE); - widget_set_font(cmdline_widget, "Courier"); - g_signal_connect(G_OBJECT(cmdline_widget), "key-press-event", - G_CALLBACK(cmdline_key_pressed), NULL); - gtk_box_pack_start(GTK_BOX(vbox), cmdline_widget, FALSE, FALSE, 0); - - gtk_container_add(GTK_CONTAINER(window), vbox); - - filename_popup = GTK_INFO_POPUP(gtk_info_popup_new(cmdline_widget)); - - editor_msg(SCI_SETFOCUS, 1); - editor_msg(SCI_SETCARETSTYLE, 2); - editor_msg(SCI_STYLESETFONT, STYLE_DEFAULT, (sptr_t)"Courier"); - editor_msg(SCI_STYLECLEARALL); - editor_msg(SCI_SETLEXER, SCLEX_CPP); - editor_msg(SCI_SETKEYWORDS, 0, (sptr_t)"int char"); - editor_msg(SCI_STYLESETFORE, SCE_C_COMMENT, 0x008000); - editor_msg(SCI_STYLESETFORE, SCE_C_COMMENTLINE, 0x008000); - editor_msg(SCI_STYLESETFORE, SCE_C_NUMBER, 0x808000); - editor_msg(SCI_STYLESETFORE, SCE_C_WORD, 0x800000); - editor_msg(SCI_STYLESETFORE, SCE_C_STRING, 0x800080); - editor_msg(SCI_STYLESETBOLD, SCE_C_OPERATOR, 1); + interface.ssm(SCI_SETFOCUS, 1); + interface.ssm(SCI_SETCARETSTYLE, 2); + interface.ssm(SCI_STYLESETFONT, STYLE_DEFAULT, (sptr_t)"Courier"); + interface.ssm(SCI_STYLECLEARALL); + interface.ssm(SCI_SETLEXER, SCLEX_CPP); + interface.ssm(SCI_SETKEYWORDS, 0, (sptr_t)"int char"); + interface.ssm(SCI_STYLESETFORE, SCE_C_COMMENT, 0x008000); + interface.ssm(SCI_STYLESETFORE, SCE_C_COMMENTLINE, 0x008000); + interface.ssm(SCI_STYLESETFORE, SCE_C_NUMBER, 0x808000); + interface.ssm(SCI_STYLESETFORE, SCE_C_WORD, 0x800000); + interface.ssm(SCI_STYLESETFORE, SCE_C_STRING, 0x800080); + interface.ssm(SCI_STYLESETBOLD, SCE_C_OPERATOR, 1); qregisters.initialize(); ring.edit(NULL); /* add remaining arguments to unnamed buffer */ for (int i = 1; i < argc; i++) { - editor_msg(SCI_ADDTEXT, strlen(argv[i]), (sptr_t)argv[i]); - editor_msg(SCI_ADDTEXT, 1, (sptr_t)"\r"); + interface.ssm(SCI_ADDTEXT, strlen(argv[i]), (sptr_t)argv[i]); + interface.ssm(SCI_ADDTEXT, 1, (sptr_t)"\r"); } - editor_msg(SCI_GOTOPOS, 0); + interface.ssm(SCI_GOTOPOS, 0); if (g_file_test(mung_file, G_FILE_TEST_IS_REGULAR)) { if (!file_execute(mung_file)) @@ -243,11 +96,9 @@ main(int argc, char **argv) undo.enabled = true; - cmdline_display("*"); - gtk_widget_grab_focus(cmdline_widget); + interface.cmdline_update("*"); - gtk_widget_show_all(window); - gtk_main(); + interface.event_loop(); return 0; } @@ -5,6 +5,7 @@ #include <glib/gstdio.h> #include "sciteco.h" +#include "interface.h" #include "undo.h" #include "expressions.h" #include "goto.h" @@ -53,9 +54,8 @@ macro_execute(const gchar *macro) #endif if (!State::input(macro[macro_pc])) { - message_display(GTK_MESSAGE_ERROR, - "Syntax error \"%c\"", - macro[macro_pc]); + interface.msg(Interface::MSG_ERROR, + "Syntax error \"%c\"", macro[macro_pc]); return false; } @@ -344,12 +344,12 @@ StateStart::StateStart() : State() tecoBool StateStart::move_chars(gint64 n) { - sptr_t pos = editor_msg(SCI_GETCURRENTPOS); + sptr_t pos = interface.ssm(SCI_GETCURRENTPOS); if (!Validate::pos(pos + n)) return FAILURE; - editor_msg(SCI_GOTOPOS, pos + n); + interface.ssm(SCI_GOTOPOS, pos + n); undo.push_msg(SCI_GOTOPOS, pos); return SUCCESS; } @@ -357,13 +357,13 @@ StateStart::move_chars(gint64 n) tecoBool StateStart::move_lines(gint64 n) { - sptr_t pos = editor_msg(SCI_GETCURRENTPOS); - sptr_t line = editor_msg(SCI_LINEFROMPOSITION, pos) + n; + sptr_t pos = interface.ssm(SCI_GETCURRENTPOS); + sptr_t line = interface.ssm(SCI_LINEFROMPOSITION, pos) + n; if (!Validate::line(line)) return FAILURE; - editor_msg(SCI_GOTOLINE, line); + interface.ssm(SCI_GOTOLINE, line); undo.push_msg(SCI_GOTOPOS, pos); return SUCCESS; } @@ -376,9 +376,9 @@ StateStart::delete_words(gint64 n) if (!n) return SUCCESS; - pos = editor_msg(SCI_GETCURRENTPOS); - size = editor_msg(SCI_GETLENGTH); - editor_msg(SCI_BEGINUNDOACTION); + pos = interface.ssm(SCI_GETCURRENTPOS); + size = interface.ssm(SCI_GETLENGTH); + interface.ssm(SCI_BEGINUNDOACTION); /* * FIXME: would be nice to do this with constant amount of * editor messages. E.g. by using custom algorithm accessing @@ -386,28 +386,28 @@ StateStart::delete_words(gint64 n) */ if (n > 0) { while (n--) { - sptr_t size = editor_msg(SCI_GETLENGTH); - editor_msg(SCI_DELWORDRIGHTEND); - if (size == editor_msg(SCI_GETLENGTH)) + sptr_t size = interface.ssm(SCI_GETLENGTH); + interface.ssm(SCI_DELWORDRIGHTEND); + if (size == interface.ssm(SCI_GETLENGTH)) break; } } else { n *= -1; while (n--) { - sptr_t pos = editor_msg(SCI_GETCURRENTPOS); - //editor_msg(SCI_DELWORDLEFTEND); - editor_msg(SCI_WORDLEFTEND); - if (pos == editor_msg(SCI_GETCURRENTPOS)) + sptr_t pos = interface.ssm(SCI_GETCURRENTPOS); + //interface.ssm(SCI_DELWORDLEFTEND); + interface.ssm(SCI_WORDLEFTEND); + if (pos == interface.ssm(SCI_GETCURRENTPOS)) break; - editor_msg(SCI_DELWORDRIGHTEND); + interface.ssm(SCI_DELWORDRIGHTEND); } } - editor_msg(SCI_ENDUNDOACTION); + interface.ssm(SCI_ENDUNDOACTION); if (n >= 0) { - if (size != editor_msg(SCI_GETLENGTH)) { - editor_msg(SCI_UNDO); - editor_msg(SCI_GOTOPOS, pos); + if (size != interface.ssm(SCI_GETLENGTH)) { + interface.ssm(SCI_UNDO); + interface.ssm(SCI_GOTOPOS, pos); } return FAILURE; } @@ -498,20 +498,20 @@ StateStart::custom(gchar chr) case '.': BEGIN_EXEC(this); expressions.eval(); - expressions.push(editor_msg(SCI_GETCURRENTPOS)); + expressions.push(interface.ssm(SCI_GETCURRENTPOS)); break; case 'Z': BEGIN_EXEC(this); expressions.eval(); - expressions.push(editor_msg(SCI_GETLENGTH)); + expressions.push(interface.ssm(SCI_GETLENGTH)); break; case 'H': BEGIN_EXEC(this); expressions.eval(); expressions.push(0); - expressions.push(editor_msg(SCI_GETLENGTH)); + expressions.push(interface.ssm(SCI_GETLENGTH)); break; /* @@ -648,8 +648,8 @@ StateStart::custom(gchar chr) v = expressions.pop_num_calc(1, 0); if (Validate::pos(v)) { undo.push_msg(SCI_GOTOPOS, - editor_msg(SCI_GETCURRENTPOS)); - editor_msg(SCI_GOTOPOS, v); + interface.ssm(SCI_GETCURRENTPOS)); + interface.ssm(SCI_GOTOPOS, v); if (eval_colon()) expressions.push(SUCCESS); @@ -703,7 +703,7 @@ StateStart::custom(gchar chr) BEGIN_EXEC(this); v = expressions.pop_num_calc(); - pos = editor_msg(SCI_GETCURRENTPOS); + pos = interface.ssm(SCI_GETCURRENTPOS); /* * FIXME: would be nice to do this with constant amount of * editor messages. E.g. by using custom algorithm accessing @@ -714,9 +714,9 @@ StateStart::custom(gchar chr) msg = SCI_WORDLEFTEND; } while (v--) { - sptr_t pos = editor_msg(SCI_GETCURRENTPOS); - editor_msg(msg); - if (pos == editor_msg(SCI_GETCURRENTPOS)) + sptr_t pos = interface.ssm(SCI_GETCURRENTPOS); + interface.ssm(msg); + if (pos == interface.ssm(SCI_GETCURRENTPOS)) break; } if (v < 0) { @@ -724,7 +724,7 @@ StateStart::custom(gchar chr) if (eval_colon()) expressions.push(SUCCESS); } else { - editor_msg(SCI_GOTOPOS, pos); + interface.ssm(SCI_GOTOPOS, pos); if (eval_colon()) expressions.push(FAILURE); else @@ -753,8 +753,8 @@ StateStart::custom(gchar chr) case '=': BEGIN_EXEC(this); - message_display(GTK_MESSAGE_OTHER, "%" G_GINT64_FORMAT, - expressions.pop_num_calc()); + interface.msg(Interface::MSG_USER, "%" G_GINT64_FORMAT, + expressions.pop_num_calc()); break; case 'K': @@ -765,15 +765,15 @@ StateStart::custom(gchar chr) expressions.eval(); if (expressions.args() <= 1) { - from = editor_msg(SCI_GETCURRENTPOS); + from = interface.ssm(SCI_GETCURRENTPOS); if (chr == 'D') { len = expressions.pop_num_calc(); rc = TECO_BOOL(Validate::pos(from + len)); } else /* chr == 'K' */ { sptr_t line; - line = editor_msg(SCI_LINEFROMPOSITION, from) + + line = interface.ssm(SCI_LINEFROMPOSITION, from) + expressions.pop_num_calc(); - len = editor_msg(SCI_POSITIONFROMLINE, line) + len = interface.ssm(SCI_POSITIONFROMLINE, line) - from; rc = TECO_BOOL(Validate::line(line)); } @@ -797,12 +797,12 @@ StateStart::custom(gchar chr) if (len == 0 || IS_FAILURE(rc)) break; - undo.push_msg(SCI_GOTOPOS, editor_msg(SCI_GETCURRENTPOS)); + undo.push_msg(SCI_GOTOPOS, interface.ssm(SCI_GETCURRENTPOS)); undo.push_msg(SCI_UNDO); - editor_msg(SCI_BEGINUNDOACTION); - editor_msg(SCI_DELETERANGE, from, len); - editor_msg(SCI_ENDUNDOACTION); + interface.ssm(SCI_BEGINUNDOACTION); + interface.ssm(SCI_DELETERANGE, from, len); + interface.ssm(SCI_ENDUNDOACTION); break; } @@ -1089,14 +1089,14 @@ StateInsert::initial(void) if (!args) return; - editor_msg(SCI_BEGINUNDOACTION); + interface.ssm(SCI_BEGINUNDOACTION); for (int i = args; i > 0; i--) { gchar chr = (gchar)expressions.peek_num(i); - editor_msg(SCI_ADDTEXT, 1, (sptr_t)&chr); + interface.ssm(SCI_ADDTEXT, 1, (sptr_t)&chr); } for (int i = args; i > 0; i--) expressions.pop_num_calc(); - editor_msg(SCI_ENDUNDOACTION); + interface.ssm(SCI_ENDUNDOACTION); undo.push_msg(SCI_UNDO); } @@ -1104,10 +1104,10 @@ StateInsert::initial(void) void StateInsert::process(const gchar *str, gint new_chars) { - editor_msg(SCI_BEGINUNDOACTION); - editor_msg(SCI_ADDTEXT, new_chars, + interface.ssm(SCI_BEGINUNDOACTION); + interface.ssm(SCI_ADDTEXT, new_chars, (sptr_t)(str + strlen(str) - new_chars)); - editor_msg(SCI_ENDUNDOACTION); + interface.ssm(SCI_ENDUNDOACTION); undo.push_msg(SCI_UNDO); } @@ -1126,7 +1126,7 @@ StateSearch::initial(void) undo.push_var<Parameters>(parameters); - parameters.dot = editor_msg(SCI_GETCURRENTPOS); + parameters.dot = interface.ssm(SCI_GETCURRENTPOS); v = expressions.pop_num_calc(); if (expressions.args()) { /* TODO: optional count argument? */ @@ -1137,7 +1137,7 @@ StateSearch::initial(void) parameters.count = (gint)v; if (v >= 0) { parameters.from = parameters.dot; - parameters.to = editor_msg(SCI_GETLENGTH); + parameters.to = interface.ssm(SCI_GETLENGTH); } else { parameters.from = 0; parameters.to = parameters.dot; @@ -1360,7 +1360,7 @@ StateSearch::process(const gchar *str, gint new_chars __attribute__((unused))) gint matched_from = -1, matched_to = -1; - undo.push_msg(SCI_GOTOPOS, editor_msg(SCI_GETCURRENTPOS)); + undo.push_msg(SCI_GOTOPOS, interface.ssm(SCI_GETCURRENTPOS)); undo.push_var<gint64>(search_reg->integer); search_reg->integer = FAILURE; @@ -1371,18 +1371,18 @@ StateSearch::process(const gchar *str, gint new_chars __attribute__((unused))) g_printf("REGEXP: %s\n", re_pattern); #endif if (!re_pattern) { - editor_msg(SCI_GOTOPOS, parameters.dot); + interface.ssm(SCI_GOTOPOS, parameters.dot); return; } re = g_regex_new(re_pattern, (GRegexCompileFlags)flags, (GRegexMatchFlags)0, NULL); g_free(re_pattern); if (!re) { - editor_msg(SCI_GOTOPOS, parameters.dot); + interface.ssm(SCI_GOTOPOS, parameters.dot); return; } - buffer = (const gchar *)editor_msg(SCI_GETCHARACTERPOINTER); + buffer = (const gchar *)interface.ssm(SCI_GETCHARACTERPOINTER); g_regex_match_full(re, buffer, (gssize)parameters.to, parameters.from, (GRegexMatchFlags)0, &info, NULL); @@ -1428,9 +1428,9 @@ StateSearch::process(const gchar *str, gint new_chars __attribute__((unused))) if (matched_from >= 0 && matched_to >= 0) { /* match success */ search_reg->integer = SUCCESS; - editor_msg(SCI_SETSEL, matched_from, matched_to); + interface.ssm(SCI_SETSEL, matched_from, matched_to); } else { - editor_msg(SCI_GOTOPOS, parameters.dot); + interface.ssm(SCI_GOTOPOS, parameters.dot); } g_regex_unref(re); @@ -1456,7 +1456,7 @@ StateSearch::done(const gchar *str) expressions.push(search_reg->integer); else if (IS_FAILURE(search_reg->integer) && !expressions.find_op(Expressions::OP_LOOP) /* not in loop */) - message_display(GTK_MESSAGE_ERROR, "Search string not found!"); + interface.msg(Interface::MSG_ERROR, "Search string not found!"); return &States::start; } @@ -6,6 +6,9 @@ #include "sciteco.h" +/* TECO uses only lower 7 bits for commands */ +#define MAX_TRANSITIONS 127 + class State { protected: /* static transitions */ diff --git a/qbuffers.cpp b/qbuffers.cpp index b9afbd6..f12ed3c 100644 --- a/qbuffers.cpp +++ b/qbuffers.cpp @@ -11,11 +11,10 @@ #include <glib/gprintf.h> #include <glib/gstdio.h> -#include "gtk-info-popup.h" - #include <Scintilla.h> #include "sciteco.h" +#include "interface.h" #include "undo.h" #include "parser.h" #include "expressions.h" @@ -45,7 +44,7 @@ static QRegister *register_argument = NULL; static inline void current_save_dot(void) { - gint dot = editor_msg(SCI_GETCURRENTPOS); + gint dot = interface.ssm(SCI_GETCURRENTPOS); if (ring.current) ring.current->dot = dot; @@ -68,9 +67,9 @@ QRegister::set_string(const gchar *str) edit(); dot = 0; - editor_msg(SCI_BEGINUNDOACTION); - editor_msg(SCI_SETTEXT, 0, (sptr_t)str); - editor_msg(SCI_ENDUNDOACTION); + interface.ssm(SCI_BEGINUNDOACTION); + interface.ssm(SCI_SETTEXT, 0, (sptr_t)str); + interface.ssm(SCI_ENDUNDOACTION); current_edit(); } @@ -99,9 +98,9 @@ QRegister::get_string(void) current_save_dot(); edit(); - size = editor_msg(SCI_GETLENGTH) + 1; + size = interface.ssm(SCI_GETLENGTH) + 1; str = (gchar *)g_malloc(size); - editor_msg(SCI_GETTEXT, size, (sptr_t)str); + interface.ssm(SCI_GETTEXT, size, (sptr_t)str); current_edit(); @@ -122,10 +121,10 @@ QRegister::load(const gchar *filename) if (!g_file_get_contents(filename, &contents, &size, NULL)) return false; - editor_msg(SCI_BEGINUNDOACTION); - editor_msg(SCI_CLEARALL); - editor_msg(SCI_APPENDTEXT, size, (sptr_t)contents); - editor_msg(SCI_ENDUNDOACTION); + interface.ssm(SCI_BEGINUNDOACTION); + interface.ssm(SCI_CLEARALL); + interface.ssm(SCI_APPENDTEXT, size, (sptr_t)contents); + interface.ssm(SCI_ENDUNDOACTION); g_free(contents); @@ -164,16 +163,16 @@ Buffer::load(const gchar *filename) gsize size; edit(); - editor_msg(SCI_CLEARALL); + interface.ssm(SCI_CLEARALL); /* FIXME: prevent excessive allocations by reading file into buffer */ if (!g_file_get_contents(filename, &contents, &size, NULL)) return false; - editor_msg(SCI_APPENDTEXT, size, (sptr_t)contents); + interface.ssm(SCI_APPENDTEXT, size, (sptr_t)contents); g_free(contents); - editor_msg(SCI_GOTOPOS, 0); - editor_msg(SCI_SETSAVEPOINT); + interface.ssm(SCI_GOTOPOS, 0); + interface.ssm(SCI_SETSAVEPOINT); set_filename(filename); @@ -186,12 +185,12 @@ Buffer::close(void) LIST_REMOVE(this, buffers); if (filename) - message_display(GTK_MESSAGE_INFO, - "Removed file \"%s\" from the ring", - filename); + interface.msg(Interface::MSG_INFO, + "Removed file \"%s\" from the ring", + filename); else - message_display(GTK_MESSAGE_INFO, - "Removed unnamed file from the ring."); + interface.msg(Interface::MSG_INFO, + "Removed unnamed file from the ring."); } void @@ -243,19 +242,19 @@ Ring::edit(const gchar *filename) if (g_file_test(filename, G_FILE_TEST_IS_REGULAR)) { buffer->load(filename); - message_display(GTK_MESSAGE_INFO, - "Added file \"%s\" to ring", filename); + interface.msg(Interface::MSG_INFO, + "Added file \"%s\" to ring", filename); } else { buffer->edit(); buffer->set_filename(filename); if (filename) - message_display(GTK_MESSAGE_INFO, - "Added new file \"%s\" to ring", - filename); + interface.msg(Interface::MSG_INFO, + "Added new file \"%s\" to ring", + filename); else - message_display(GTK_MESSAGE_INFO, - "Added new unnamed file to ring."); + interface.msg(Interface::MSG_INFO, + "Added new unnamed file to ring."); } } @@ -307,9 +306,9 @@ public: attributes); #endif } else { - message_display(GTK_MESSAGE_WARNING, - "Unable to restore save point file \"%s\"", - savepoint); + interface.msg(Interface::MSG_WARNING, + "Unable to restore save point file \"%s\"", + savepoint); } } }; @@ -341,9 +340,9 @@ make_savepoint(Buffer *buffer) #endif undo.push(token); } else { - message_display(GTK_MESSAGE_WARNING, - "Unable to create save point file \"%s\"", - savepoint); + interface.msg(Interface::MSG_WARNING, + "Unable to create save point file \"%s\"", + savepoint); g_free(savepoint); } } @@ -372,8 +371,8 @@ Ring::save(const gchar *filename) undo.push(new UndoTokenRemoveFile(filename)); } - buffer = (const gchar *)editor_msg(SCI_GETCHARACTERPOINTER); - size = editor_msg(SCI_GETLENGTH); + buffer = (const gchar *)interface.ssm(SCI_GETCHARACTERPOINTER); + size = interface.ssm(SCI_GETLENGTH); if (!g_file_set_contents(filename, buffer, size, NULL)) return false; @@ -397,7 +396,7 @@ Ring::close(void) { Buffer *buffer = current; - buffer->dot = editor_msg(SCI_GETCURRENTPOS); + buffer->dot = interface.ssm(SCI_GETCURRENTPOS); buffer->close(); current = buffer->next() ? : first(); /* transfer responsibility to UndoToken object */ @@ -481,12 +480,11 @@ StateEditFile::initial(void) if (id == 0) { for (Buffer *cur = ring.first(); cur; cur = cur->next()) - gtk_info_popup_add_filename(filename_popup, - GTK_INFO_POPUP_FILE, - cur->filename ? : "(Unnamed)", - cur == ring.current); + interface.popup_add_filename(Interface::POPUP_FILE, + cur->filename ? : "(Unnamed)", + cur == ring.current); - gtk_widget_show(GTK_WIDGET(filename_popup)); + interface.popup_show(); } } @@ -665,10 +663,10 @@ StateCopyToQReg::got_register(QRegister *reg) expressions.eval(); if (expressions.args() <= 1) { - from = editor_msg(SCI_GETCURRENTPOS); - sptr_t line = editor_msg(SCI_LINEFROMPOSITION, from) + + from = interface.ssm(SCI_GETCURRENTPOS); + sptr_t line = interface.ssm(SCI_LINEFROMPOSITION, from) + expressions.pop_num_calc(); - len = editor_msg(SCI_POSITIONFROMLINE, line) - from; + len = interface.ssm(SCI_POSITIONFROMLINE, line) - from; if (len < 0) { from += len; @@ -683,7 +681,7 @@ StateCopyToQReg::got_register(QRegister *reg) tr.chrg.cpMin = from; tr.chrg.cpMax = from + len; tr.lpstrText = (char *)g_malloc(len + 1); - editor_msg(SCI_GETTEXTRANGE, 0, (sptr_t)&tr); + interface.ssm(SCI_GETTEXTRANGE, 0, (sptr_t)&tr); reg->undo_set_string(); reg->set_string(tr.lpstrText); @@ -1,26 +1,14 @@ #ifndef __SCITECO_H #define __SCITECO_H -#include <stdarg.h> - #include <glib.h> -#include <gtk/gtk.h> -#include "gtk-info-popup.h" -#include <Scintilla.h> +#include "interface.h" extern gchar *cmdline; extern bool quit_requested; -extern GtkInfoPopup *filename_popup; - -void message_display(GtkMessageType type, - const gchar *fmt, ...) G_GNUC_PRINTF(2, 3); - void cmdline_keypress(gchar key); -void cmdline_display(const gchar *cmdline); - -sptr_t editor_msg(unsigned int iMessage, uptr_t wParam = 0, sptr_t lParam = 0); #define IS_CTL(C) ((C) < ' ') #define CTL_ECHO(C) ((C) | 0x40) @@ -35,9 +23,6 @@ typedef gint64 tecoBool; #define IS_SUCCESS(X) ((X) < 0) #define IS_FAILURE(X) (!IS_SUCCESS(X)) -/* TECO uses only lower 7 bits for commands */ -#define MAX_TRANSITIONS 127 - namespace String { static inline void @@ -62,13 +47,13 @@ namespace Validate { static inline bool pos(gint n) { - return n >= 0 && n <= editor_msg(SCI_GETLENGTH); + return n >= 0 && n <= interface.ssm(SCI_GETLENGTH); } static inline bool line(gint n) { - return n >= 0 && n < editor_msg(SCI_GETLINECOUNT); + return n >= 0 && n < interface.ssm(SCI_GETLINECOUNT); } } /* namespace Validate */ @@ -6,6 +6,7 @@ #include <Scintilla.h> #include "sciteco.h" +#include "interface.h" #include "undo.h" UndoStack undo; @@ -13,7 +14,7 @@ UndoStack undo; void UndoTokenMessage::run(void) { - editor_msg(iMessage, wParam, lParam); + interface.ssm(iMessage, wParam, lParam); } void |