summaryrefslogtreecommitdiff
path: root/src/gui/curses/headless
diff options
context:
space:
mode:
authorSébastien Helleu <flashcode@flashtux.org>2018-03-11 09:59:39 +0100
committerSébastien Helleu <flashcode@flashtux.org>2018-03-11 09:59:39 +0100
commit805717e9ec3f66c960928bca607eceb871438fae (patch)
treec1832f0815bd8ade4530ed3948f55f0672103184 /src/gui/curses/headless
parent0126b03f47db7f7842aff497cdbb0e41a0a5be0a (diff)
downloadweechat-805717e9ec3f66c960928bca607eceb871438fae.zip
core: add binary weechat-headless to run WeeChat without interface (closes #1120)
The optional command line option "--daemon" runs WeeChat like a daemon (fork, new process group, file descriptors closed).
Diffstat (limited to 'src/gui/curses/headless')
-rw-r--r--src/gui/curses/headless/CMakeLists.txt57
-rw-r--r--src/gui/curses/headless/Makefile.am55
-rw-r--r--src/gui/curses/headless/main.c125
-rw-r--r--src/gui/curses/headless/ncurses-fake.c433
-rw-r--r--src/gui/curses/headless/ncurses-fake.h126
5 files changed, 796 insertions, 0 deletions
diff --git a/src/gui/curses/headless/CMakeLists.txt b/src/gui/curses/headless/CMakeLists.txt
new file mode 100644
index 000000000..3aa6b4448
--- /dev/null
+++ b/src/gui/curses/headless/CMakeLists.txt
@@ -0,0 +1,57 @@
+#
+# Copyright (C) 2003-2018 Sébastien Helleu <flashcode@flashtux.org>
+#
+# This file is part of WeeChat, the extensible chat client.
+#
+# WeeChat is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# WeeChat is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with WeeChat. If not, see <http://www.gnu.org/licenses/>.
+#
+
+add_definitions(-DWEECHAT_HEADLESS)
+
+# fake ncurses lib (for headless mode and tests)
+set(LIB_WEECHAT_NCURSES_FAKE_SRC
+ ncurses-fake.h
+ ncurses-fake.c
+)
+add_library(weechat_ncurses_fake STATIC ${LIB_WEECHAT_NCURSES_FAKE_SRC})
+
+set(LIB_GUI_CURSES_SRC
+ ../gui-curses.h
+ ../gui-curses-bar-window.c
+ ../gui-curses-chat.c
+ ../gui-curses-color.c
+ ../gui-curses-key.c
+ ../gui-curses-main.c
+ ../gui-curses-mouse.c
+ ../gui-curses-term.c
+ ../gui-curses-window.c
+)
+
+include_directories(. .. ../../core ../../plugins)
+
+add_library(weechat_gui_headless STATIC ${LIB_GUI_CURSES_SRC})
+
+set(WEECHAT_CURSES_MAIN_HEADLESS_SRC main.c)
+
+set(EXECUTABLE weechat-headless)
+
+add_executable(${EXECUTABLE} ${WEECHAT_CURSES_MAIN_HEADLESS_SRC})
+
+add_dependencies(${EXECUTABLE} weechat_gui_headless weechat_ncurses_fake)
+
+# Due to circular references, we must link two times with libweechat_core.a and libweechat_gui_common.a
+target_link_libraries(${EXECUTABLE} ${STATIC_LIBS} weechat_gui_headless weechat_ncurses_fake ${EXTRA_LIBS} ${STATIC_LIBS})
+
+# Install executable
+install(TARGETS ${EXECUTABLE} RUNTIME DESTINATION bin)
diff --git a/src/gui/curses/headless/Makefile.am b/src/gui/curses/headless/Makefile.am
new file mode 100644
index 000000000..08c2d164e
--- /dev/null
+++ b/src/gui/curses/headless/Makefile.am
@@ -0,0 +1,55 @@
+#
+# Copyright (C) 2003-2018 Sébastien Helleu <flashcode@flashtux.org>
+#
+# This file is part of WeeChat, the extensible chat client.
+#
+# WeeChat is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# WeeChat is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with WeeChat. If not, see <http://www.gnu.org/licenses/>.
+#
+
+AM_CPPFLAGS = -DLOCALEDIR=\"$(datadir)/locale\" -DWEECHAT_HEADLESS
+
+noinst_LIBRARIES = lib_weechat_ncurses_fake.a lib_weechat_gui_headless.a
+
+lib_weechat_ncurses_fake_a_SOURCES = ncurses-fake.c \
+ ncurses-fake.h
+
+lib_weechat_gui_headless_a_SOURCES = ../gui-curses-bar-window.c \
+ ../gui-curses-chat.c \
+ ../gui-curses-color.c \
+ ../gui-curses-key.c \
+ ../gui-curses-main.c \
+ ../gui-curses-mouse.c \
+ ../gui-curses-term.c \
+ ../gui-curses-window.c \
+ ../gui-curses.h
+
+bin_PROGRAMS = weechat-headless
+
+# Due to circular references, we must link two times with libweechat_core.a
+# (and with two different path/names to be kept by linker)
+weechat_headless_LDADD = ./../../../core/lib_weechat_core.a \
+ ../../../plugins/lib_weechat_plugins.a \
+ ../../lib_weechat_gui_common.a \
+ lib_weechat_gui_headless.a \
+ lib_weechat_ncurses_fake.a \
+ ../../../core/lib_weechat_core.a \
+ $(PLUGINS_LFLAGS) \
+ $(GCRYPT_LFLAGS) \
+ $(GNUTLS_LFLAGS) \
+ $(CURL_LFLAGS) \
+ -lm
+
+weechat_headless_SOURCES = main.c
+
+EXTRA_DIST = CMakeLists.txt
diff --git a/src/gui/curses/headless/main.c b/src/gui/curses/headless/main.c
new file mode 100644
index 000000000..481177020
--- /dev/null
+++ b/src/gui/curses/headless/main.c
@@ -0,0 +1,125 @@
+/*
+ * main.c - entry point for headless mode (no GUI)
+ *
+ * Copyright (C) 2003-2018 Sébastien Helleu <flashcode@flashtux.org>
+ *
+ * This file is part of WeeChat, the extensible chat client.
+ *
+ * WeeChat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * WeeChat is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with WeeChat. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "../../../core/weechat.h"
+#include "../../gui-main.h"
+#include "../gui-curses.h"
+
+
+/*
+ * Daemonizes the process.
+ */
+
+void
+daemonize ()
+{
+ pid_t pid;
+ int fd, i;
+
+ printf (_("Running WeeChat in background..."));
+ printf (" ");
+
+ pid = fork();
+
+ if (pid < 0)
+ {
+ printf (_("fork error"));
+ printf ("\n");
+ exit (EXIT_FAILURE);
+ }
+
+ if (pid > 0)
+ {
+ /* parent process */
+ printf (_("OK"));
+ printf ("\n");
+ exit (EXIT_SUCCESS);
+ }
+
+ /* child process */
+
+ /* obtain a new process group */
+ setsid ();
+
+ /* close all file descriptors */
+ for (i = getdtablesize(); i >= 0; --i)
+ {
+ close (i);
+ }
+ fd = open ("/dev/null", O_RDWR);
+ dup (fd);
+ dup (fd);
+}
+
+/*
+ * Entry point for WeeChat in headless mode (no GUI).
+ */
+
+int
+main (int argc, char *argv[])
+{
+ int i, daemon;
+
+ weechat_init_gettext ();
+
+ /*
+ * Enable a special "headless" mode, where some things are slightly
+ * different, for example:
+ * - no read of stdin (keyboard/mouse)
+ * - don't catch any terminal related signal
+ */
+ weechat_headless = 1;
+
+ /*
+ * If "--daemon" is received in command line arguments,
+ * daemonize the process.
+ */
+ daemon = 0;
+ for (i = 1; i < argc; i++)
+ {
+ if (strcmp (argv[i], "--daemon") == 0)
+ {
+ daemon = 1;
+ break;
+ }
+ }
+ if (daemon)
+ daemonize ();
+
+ /* init, main loop and end */
+ weechat_init (argc, argv, &gui_main_init);
+ gui_main_loop ();
+ weechat_end (&gui_main_end);
+
+ return EXIT_SUCCESS;
+}
diff --git a/src/gui/curses/headless/ncurses-fake.c b/src/gui/curses/headless/ncurses-fake.c
new file mode 100644
index 000000000..da1e4ac8d
--- /dev/null
+++ b/src/gui/curses/headless/ncurses-fake.c
@@ -0,0 +1,433 @@
+/*
+ * ncurses-fake.c - fake ncurses lib (for headless mode and tests)
+ *
+ * Copyright (C) 2014-2018 Sébastien Helleu <flashcode@flashtux.org>
+ *
+ * This file is part of WeeChat, the extensible chat client.
+ *
+ * WeeChat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * WeeChat is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with WeeChat. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "ncurses-fake.h"
+
+
+/* simulate 80x25 terminal */
+WINDOW _stdscr = { 0, 0, 24, 79, 0, 0 };
+WINDOW *stdscr = &_stdscr;
+chtype acs_map[256];
+
+
+WINDOW *
+initscr ()
+{
+ return stdscr;
+}
+
+int
+endwin ()
+{
+ return OK;
+}
+
+WINDOW *
+newwin (int nlines, int ncols, int begin_y, int begin_x)
+{
+ (void) nlines;
+ (void) ncols;
+ (void) begin_y;
+ (void) begin_x;
+
+ return stdscr;
+}
+
+int
+delwin (WINDOW *win)
+{
+ (void) win;
+
+ return OK;
+}
+
+int
+move (int y, int x)
+{
+ (void) y;
+ (void) x;
+
+ return OK;
+}
+
+int
+wmove (WINDOW *win, int y, int x)
+{
+ (void) win;
+ (void) y;
+ (void) x;
+
+ return OK;
+}
+
+int
+wattr_on (WINDOW *win, attr_t attrs, void *opts)
+{
+ (void) win;
+ (void) attrs;
+ (void) opts;
+
+ return OK;
+}
+
+int
+wattr_off (WINDOW *win, attr_t attrs, void *opts)
+{
+ (void) win;
+ (void) attrs;
+ (void) opts;
+
+ return OK;
+}
+
+int
+wattr_get (WINDOW *win, attr_t *attrs, short *pair, void *opts)
+{
+ (void) win;
+ (void) attrs;
+ (void) pair;
+ (void) opts;
+
+ return OK;
+}
+
+int
+wattr_set (WINDOW *win, attr_t attrs, short pair, void *opts)
+{
+ (void) win;
+ (void) attrs;
+ (void) pair;
+ (void) opts;
+
+ return OK;
+}
+
+int
+wattron (WINDOW *win, int attrs)
+{
+ (void) win;
+ (void) attrs;
+
+ return OK;
+}
+
+int
+wattroff (WINDOW *win, int attrs)
+{
+ (void) win;
+ (void) attrs;
+
+ return OK;
+}
+
+int
+waddstr (WINDOW *win, const char *str)
+{
+ (void) win;
+ (void) str;
+
+ return OK;
+}
+
+int
+waddnstr (WINDOW *win, const char *str, int n)
+{
+ (void) win;
+ (void) str;
+ (void) n;
+
+ return OK;
+}
+
+int
+mvaddstr (int y, int x, const char *str)
+{
+ (void) y;
+ (void) x;
+ (void) str;
+
+ return OK;
+}
+
+int
+mvwaddstr (WINDOW *win, int y, int x, const char *str)
+{
+ (void) win;
+ (void) y;
+ (void) x;
+ (void) str;
+
+ return OK;
+}
+
+int
+wclrtobot (WINDOW *win)
+{
+ (void) win;
+
+ return OK;
+}
+
+int
+refresh ()
+{
+ return OK;
+}
+
+int
+wrefresh (WINDOW *win)
+{
+ (void) win;
+
+ return OK;
+}
+
+int
+wnoutrefresh (WINDOW *win)
+{
+ (void) win;
+
+ return OK;
+}
+
+int
+wclrtoeol (WINDOW *win)
+{
+ (void) win;
+
+ return OK;
+}
+
+int
+mvwprintw (WINDOW *win, int y, int x, const char *fmt, ...)
+{
+ (void) win;
+ (void) y;
+ (void) x;
+ (void) fmt;
+
+ return OK;
+}
+
+int
+init_pair (short pair, short f, short b)
+{
+ (void) pair;
+ (void) f;
+ (void) b;
+
+ return OK;
+}
+
+bool
+has_colors ()
+{
+ return TRUE;
+}
+
+int
+cbreak ()
+{
+ return OK;
+}
+
+int
+start_color ()
+{
+ return OK;
+}
+
+int
+noecho ()
+{
+ return OK;
+}
+
+int
+clear ()
+{
+ return OK;
+}
+
+int
+wclear (WINDOW *win)
+{
+ (void) win;
+
+ return OK;
+}
+
+bool
+can_change_color ()
+{
+ /* not supported in WeeChat anyway */
+ return FALSE;
+}
+
+int
+curs_set (int visibility)
+{
+ (void) visibility;
+
+ return 1; /* 0 == invisible, 1 == normal, 2 == very visible */
+}
+
+int
+nodelay (WINDOW *win, bool bf)
+{
+ (void) win;
+ (void) bf;
+
+ return OK;
+}
+
+int
+werase (WINDOW *win)
+{
+ (void) win;
+
+ return OK;
+}
+
+int
+wbkgdset (WINDOW *win, chtype ch)
+{
+ (void) win;
+ (void) ch;
+
+ return OK;
+}
+
+void
+wchgat (WINDOW *win, int n, attr_t attr, short color, const void *opts)
+{
+ (void) win;
+ (void) n;
+ (void) attr;
+ (void) color;
+ (void) opts;
+}
+
+int
+mvwchgat (WINDOW *win, int y, int x, int n, attr_t attr, short pair,
+ const void *opts)
+{
+ (void) win;
+ (void) y;
+ (void) x;
+ (void) n;
+ (void) attr;
+ (void) pair;
+ (void) opts;
+
+ return OK;
+}
+
+
+void
+whline (WINDOW *win, chtype ch, int n)
+{
+ (void) win;
+ (void) ch;
+ (void) n;
+}
+
+void
+wvline (WINDOW *win, chtype ch, int n)
+{
+ (void) win;
+ (void) ch;
+ (void) n;
+}
+
+int
+mvwhline (WINDOW *win, int y, int x, chtype ch, int n)
+{
+ (void) win;
+ (void) y;
+ (void) x;
+ (void) ch;
+ (void) n;
+
+ return OK;
+}
+
+int
+mvwvline (WINDOW *win, int y, int x, chtype ch, int n)
+{
+ (void) win;
+ (void) y;
+ (void) x;
+ (void) ch;
+ (void) n;
+
+ return OK;
+}
+
+int
+raw ()
+{
+ return OK;
+}
+
+int
+wcolor_set (WINDOW *win, short pair, void *opts)
+{
+ (void) win;
+ (void) pair;
+ (void) opts;
+
+ return OK;
+}
+
+void
+cur_term ()
+{
+}
+
+int
+use_default_colors ()
+{
+ return OK;
+}
+
+int
+resizeterm (int lines, int columns)
+{
+ (void) lines;
+ (void) columns;
+
+ return OK;
+}
+
+int
+getch ()
+{
+ return ERR;
+}
+
+int
+wgetch (WINDOW *win)
+{
+ (void) win;
+
+ return OK;
+}
diff --git a/src/gui/curses/headless/ncurses-fake.h b/src/gui/curses/headless/ncurses-fake.h
new file mode 100644
index 000000000..79ce6fc25
--- /dev/null
+++ b/src/gui/curses/headless/ncurses-fake.h
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2014-2018 Sébastien Helleu <flashcode@flashtux.org>
+ *
+ * This file is part of WeeChat, the extensible chat client.
+ *
+ * WeeChat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * WeeChat is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with WeeChat. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef WEECHAT_NCURSES_FAKE_H
+#define WEECHAT_NCURSES_FAKE_H
+
+#define ERR (-1)
+#define OK (0)
+
+#define TRUE 1
+#define FALSE 0
+
+#define COLS 80
+#define LINES 25
+#define COLORS 256
+#define COLOR_PAIRS 256
+
+#define COLOR_PAIR(x) x
+
+#define COLOR_BLACK 0
+#define COLOR_RED 1
+#define COLOR_GREEN 2
+#define COLOR_YELLOW 3
+#define COLOR_BLUE 4
+#define COLOR_MAGENTA 5
+#define COLOR_CYAN 6
+#define COLOR_WHITE 7
+
+#define A_BOLD 0
+#define A_UNDERLINE 0
+#define A_REVERSE 0
+#define A_ITALIC 0
+
+#define ACS_HLINE '-'
+#define ACS_VLINE '|'
+
+#define getyx(win, x, y) \
+ x = 0; \
+ y = 0;
+
+#define getmaxyx(win, x, y) \
+ x = 0; \
+ y = 0;
+
+struct _window
+{
+ int _cury, _curx;
+ int _maxy, _maxx;
+ int _begy, _begx;
+};
+typedef struct _window WINDOW;
+
+typedef unsigned char bool;
+typedef int attr_t;
+typedef unsigned chtype;
+
+extern WINDOW *stdscr;
+extern chtype acs_map[];
+
+extern WINDOW *initscr ();
+extern int endwin ();
+extern WINDOW *newwin (int nlines, int ncols, int begin_y, int begin_x);
+extern int delwin (WINDOW *win);
+extern int move (int y, int x);
+extern int wmove (WINDOW *win, int y, int x);
+extern int wattr_on (WINDOW *win, attr_t attrs, void *opts);
+extern int wattr_off (WINDOW *win, attr_t attrs, void *opts);
+extern int wattr_get (WINDOW *win, attr_t *attrs, short *pair, void *opts);
+extern int wattr_set (WINDOW *win, attr_t attrs, short pair, void *opts);
+extern int wattron (WINDOW *win, int attrs);
+extern int wattroff (WINDOW *win, int attrs);
+extern int waddstr (WINDOW *win, const char *str);
+extern int waddnstr (WINDOW *win, const char *str, int n);
+extern int mvaddstr (int y, int x, const char *str);
+extern int mvwaddstr (WINDOW *win, int y, int x, const char *str);
+extern int wclrtobot (WINDOW *win);
+extern int refresh ();
+extern int wrefresh (WINDOW *win);
+extern int wnoutrefresh (WINDOW *win);
+extern int wclrtoeol (WINDOW *win);
+extern int mvwprintw (WINDOW *win, int y, int x, const char *fmt, ...);
+extern int init_pair (short pair, short f, short b);
+extern bool has_colors ();
+extern int cbreak ();
+extern int start_color ();
+extern int noecho ();
+extern int clear ();
+extern int wclear (WINDOW *win);
+extern bool can_change_color ();
+extern int curs_set (int visibility);
+extern int nodelay (WINDOW *win, bool bf);
+extern int werase (WINDOW *win);
+extern int wbkgdset (WINDOW *win, chtype ch);
+extern void wchgat (WINDOW *win, int n, attr_t attr, short color,
+ const void *opts);
+extern int mvwchgat (WINDOW *win, int y, int x, int n, attr_t attr, short pair,
+ const void *opts);
+extern void whline (WINDOW *win, chtype ch, int n);
+extern void wvline (WINDOW *win, chtype ch, int n);
+extern int mvwhline (WINDOW *win, int y, int x, chtype ch, int n);
+extern int mvwvline (WINDOW *win, int y, int x, chtype ch, int n);
+extern int raw ();
+extern int wcolor_set (WINDOW *win, short pair, void *opts);
+extern void cur_term ();
+extern int use_default_colors ();
+extern int resizeterm ();
+extern int getch ();
+extern int wgetch (WINDOW *win);
+
+#endif /* WEECHAT_NCURSES_FAKE_H */