diff options
-rw-r--r-- | interface-gtk.cpp | 26 | ||||
-rw-r--r-- | interface-gtk.h | 4 | ||||
-rw-r--r-- | interface-ncurses.cpp | 39 | ||||
-rw-r--r-- | interface-ncurses.h | 7 | ||||
-rw-r--r-- | interface.h | 18 | ||||
-rw-r--r-- | main.cpp | 24 |
6 files changed, 86 insertions, 32 deletions
diff --git a/interface-gtk.cpp b/interface-gtk.cpp index d049045..38100fe 100644 --- a/interface-gtk.cpp +++ b/interface-gtk.cpp @@ -73,7 +73,7 @@ InterfaceGtk::InterfaceGtk() } void -InterfaceGtk::msg(MessageType type, const gchar *fmt, ...) +InterfaceGtk::vmsg(MessageType type, const gchar *fmt, va_list ap) { static const GtkMessageType type2gtk[] = { /* [MSG_USER] = */ GTK_MESSAGE_OTHER, @@ -82,27 +82,13 @@ InterfaceGtk::msg(MessageType type, const gchar *fmt, ...) /* [MSG_ERROR] = */ GTK_MESSAGE_ERROR }; - va_list ap; + va_list aq; 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; - } + va_copy(aq, ap); + stdio_vmsg(type, fmt, ap); + g_vsnprintf(buf, sizeof(buf), fmt, aq); + va_end(aq); gtk_info_bar_set_message_type(GTK_INFO_BAR(info_widget), type2gtk[type]); diff --git a/interface-gtk.h b/interface-gtk.h index 95a58d7..5b48ef6 100644 --- a/interface-gtk.h +++ b/interface-gtk.h @@ -1,6 +1,8 @@ #ifndef __INTERFACE_GTK_H #define __INTERFACE_GTK_H +#include <stdarg.h> + #include <glib.h> #include <gtk/gtk.h> @@ -31,7 +33,7 @@ public: gtk_parse_args(&argc, &argv); } - void msg(MessageType type, const gchar *fmt, ...) G_GNUC_PRINTF(3, 4); + void vmsg(MessageType type, const gchar *fmt, va_list ap); inline sptr_t ssm(unsigned int iMessage, uptr_t wParam = 0, sptr_t lParam = 0) diff --git a/interface-ncurses.cpp b/interface-ncurses.cpp index 48dbec6..904ae6c 100644 --- a/interface-ncurses.cpp +++ b/interface-ncurses.cpp @@ -1,9 +1,11 @@ #include <string.h> +#include <stdio.h> #include <stdarg.h> #include <locale.h> #include <glib.h> #include <glib/gprintf.h> +#include <glib/gstdio.h> #include <ncurses.h> @@ -30,7 +32,17 @@ InterfaceNCurses::InterfaceNCurses() : popup_window(NULL), popup_list(NULL), popup_list_longest(0), popup_list_length(0) { - initscr(); + /* + * Prevent the initial redraw and any escape sequences that may + * clobber stdout, so we may use the terminal in + * cooked mode, for commandline help and batch processing. + * Scintilla must be initialized for batch processing to work. + * (Frankly I have no idea why this works!) + */ + screen_tty = g_fopen("/dev/tty", "r+b"); + screen = newterm(NULL, screen_tty, screen_tty); + set_term(screen); + raw(); cbreak(); noecho(); @@ -53,10 +65,12 @@ InterfaceNCurses::InterfaceNCurses() msg(MSG_USER, " "); cmdline_update(); + + endwin(); } void -InterfaceNCurses::msg(MessageType type, const gchar *fmt, ...) +InterfaceNCurses::vmsg(MessageType type, const gchar *fmt, va_list ap) { static const short type2colorid[] = { SCI_COLOR_PAIR(COLOR_BLACK, COLOR_WHITE), /* MSG_USER */ @@ -65,13 +79,14 @@ InterfaceNCurses::msg(MessageType type, const gchar *fmt, ...) SCI_COLOR_PAIR(COLOR_BLACK, COLOR_RED) /* MSG_ERROR */ }; - va_list ap; + if (isendwin()) { /* batch mode */ + stdio_vmsg(type, fmt, ap); + return; + } wmove(msg_window, 0, 0); wbkgdset(msg_window, ' ' | COLOR_PAIR(type2colorid[type])); - va_start(ap, fmt); vw_printw(msg_window, fmt, ap); - va_end(ap); wclrtoeol(msg_window); wrefresh(msg_window); @@ -152,17 +167,22 @@ InterfaceNCurses::popup_show(void) void InterfaceNCurses::popup_clear(void) { + if (!popup_window) + return; + scintilla_refresh(sci); redrawwin(msg_window); wrefresh(msg_window); - if (popup_window) - delwin(popup_window); + delwin(popup_window); popup_window = NULL; } void InterfaceNCurses::event_loop(void) { + /* in commandline (visual) mode, enforce redraw */ + wrefresh(curscr); + for (;;) { int key; @@ -212,7 +232,10 @@ InterfaceNCurses::~InterfaceNCurses() if (popup_list) g_slist_free(popup_list); - endwin(); + if (!isendwin()) + endwin(); + delscreen(screen); + fclose(screen_tty); } /* diff --git a/interface-ncurses.h b/interface-ncurses.h index a9bcad5..9b938a2 100644 --- a/interface-ncurses.h +++ b/interface-ncurses.h @@ -1,6 +1,8 @@ #ifndef __INTERFACE_NCURSES_H #define __INTERFACE_NCURSES_H +#include <stdarg.h> + #include <glib.h> #include <ncurses.h> @@ -11,6 +13,9 @@ #include "interface.h" extern class InterfaceNCurses : public Interface { + SCREEN *screen; + FILE *screen_tty; + Scintilla *sci; WINDOW *sci_window; @@ -26,7 +31,7 @@ public: InterfaceNCurses(); ~InterfaceNCurses(); - void msg(MessageType type, const gchar *fmt, ...) G_GNUC_PRINTF(3, 4); + void vmsg(MessageType type, const gchar *fmt, va_list ap); inline sptr_t ssm(unsigned int iMessage, uptr_t wParam = 0, sptr_t lParam = 0) diff --git a/interface.h b/interface.h index 6e43392..f84649a 100644 --- a/interface.h +++ b/interface.h @@ -1,6 +1,8 @@ #ifndef __INTERFACE_H #define __INTERFACE_H +#include <stdarg.h> + #include <glib.h> #include <Scintilla.h> @@ -28,8 +30,16 @@ public: MSG_WARNING, MSG_ERROR }; - virtual void msg(MessageType type, const gchar *fmt, ...) - G_GNUC_PRINTF(3, 4) = 0; + virtual void vmsg(MessageType type, const gchar *fmt, va_list ap) = 0; + inline void + msg(MessageType type, const gchar *fmt, ...) G_GNUC_PRINTF(3, 4) + { + va_list ap; + + va_start(ap, fmt); + vmsg(type, fmt, ap); + va_end(ap); + } virtual sptr_t ssm(unsigned int iMessage, uptr_t wParam = 0, sptr_t lParam = 0) = 0; @@ -48,6 +58,10 @@ public: /* main entry point */ virtual void event_loop(void) = 0; + +protected: + /* see main.cpp */ + void stdio_vmsg(MessageType type, const gchar *fmt, va_list ap); }; #ifdef INTERFACE_GTK @@ -1,3 +1,4 @@ +#include <stdarg.h> #include <stdio.h> #include <string.h> #include <stdlib.h> @@ -19,6 +20,29 @@ static gchar *mung_file = NULL; +void +Interface::stdio_vmsg(MessageType type, const gchar *fmt, va_list ap) +{ + gchar buf[255]; + + g_vsnprintf(buf, sizeof(buf), fmt, 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; + } +} + static inline void process_options(int &argc, char **&argv) { |