00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "basewindow.h"
00021 #include "colors.h"
00022
00023 #ifdef HAVE_SIGNAL_H
00024 # include <signal.h>
00025 #endif
00026
00027 #ifdef HAVE_UNISTD_H
00028 # include <unistd.h>
00029 #endif
00030
00031 #ifdef HAVE_ALGORITHM
00032 # include <algorithm>
00033 #endif
00034
00035 using namespace YAPETUI;
00036
00037 class RemoveByAddr {
00038 private:
00039 const BaseWindow* ptr;
00040
00041 public:
00042 inline RemoveByAddr(const BaseWindow* p) : ptr(p) {}
00043 inline bool operator()(const BaseWindow* p) const {
00044 if (ptr == p)
00045 return true;
00046 return false;
00047 }
00048 };
00049
00050 class DeleteIt {
00051 public:
00052 inline void operator()(BaseWindow* p) const {
00053 if (p != NULL)
00054 delete p;
00055 }
00056 };
00057
00058 class ResizeIt {
00059 public:
00060 inline void operator()(BaseWindow* p) const {
00061 p->resize();
00062 }
00063 };
00064
00065 class RefreshIt {
00066 public:
00067 inline void operator()(BaseWindow* p) const {
00068 p->refresh();
00069 }
00070 };
00071
00072
00073
00074
00075 std::list<BaseWindow*> BaseWindow::basewindow_list = std::list<BaseWindow*>();
00076 BaseWindow::AlarmFunction* BaseWindow::alarm_fun = NULL;
00077
00078 #if defined(HAVE_SIGACTION) && defined(HAVE_SIGNAL_H)
00079 void
00080 BaseWindow::sig_handler(int signo) {
00081 switch (signo) {
00082 case SIGALRM:
00083 if (alarm_fun != NULL)
00084 alarm_fun->process(signo);
00085 break;
00086 case SIGHUP:
00087 case SIGINT:
00088 case SIGQUIT:
00089 case SIGTERM:
00090 case SIGKILL:
00091 deleteAll();
00092 endCurses();
00093 abort();
00094 }
00095 }
00096
00097 void
00098 BaseWindow::init_signal() {
00099 sigset_t sigset;
00100 sigemptyset(&sigset);
00101
00102 sigprocmask(SIG_SETMASK, NULL, &sigset);
00103
00104 sigaddset(&sigset, SIGALRM);
00105 sigaddset(&sigset, SIGTERM);
00106 sigaddset(&sigset, SIGKILL);
00107 sigaddset(&sigset, SIGQUIT);
00108 sigaddset(&sigset, SIGINT);
00109 sigaddset(&sigset, SIGHUP);
00110 sigprocmask(SIG_UNBLOCK, &sigset, NULL);
00111
00112 struct sigaction sa;
00113 sigemptyset(&sa.sa_mask);
00114 sa.sa_flags = 0;
00115 sa.sa_handler = BaseWindow::sig_handler;
00116
00117 sigaction(SIGALRM, &sa, NULL);
00118 sigaction(SIGTERM, &sa, NULL);
00119 sigaction(SIGKILL, &sa, NULL);
00120 sigaction(SIGQUIT, &sa, NULL);
00121 sigaction(SIGINT, &sa, NULL);
00122 sigaction(SIGHUP, &sa, NULL);
00123 }
00124 #endif // defined(HAVE_SIGACTION) && defined(HAVE_SIGNAL_H)
00125
00126 void
00127 BaseWindow::initCurses() {
00128 initscr();
00129 raw();
00130 noecho();
00131 ::refresh();
00132 curs_set(0);
00133 keypad (stdscr, TRUE);
00134
00135 YAPETUI::Colors::initColors();
00136 init_signal();
00137 }
00138
00139 void
00140 BaseWindow::endCurses() {
00141 clear();
00142 ::refresh();
00143 endwin();
00144 }
00145
00146 void
00147 BaseWindow::registerBaseWindow(BaseWindow* r) {
00148 basewindow_list.push_back(r);
00149 }
00150
00151 void
00152 BaseWindow::unregisterBaseWindow(BaseWindow* r) {
00153 std::list<BaseWindow*>::iterator it =
00154 std::remove_if(basewindow_list.begin(),
00155 basewindow_list.end(),
00156 RemoveByAddr(r));
00157
00158 basewindow_list.erase(it, basewindow_list.end());
00159 }
00160
00161 void
00162 BaseWindow::deleteAll() {
00163 std::for_each(basewindow_list.rbegin(),
00164 basewindow_list.rend(),
00165 DeleteIt());
00166 }
00167
00168 void
00169 BaseWindow::resizeAll() {
00170 int max_x, max_y;
00171 getmaxyx(stdscr, max_y, max_x);
00172 if (max_y < MIN_Y ||
00173 max_x < MIN_X) return;
00174 std::for_each(basewindow_list.begin(),
00175 basewindow_list.end(),
00176 ResizeIt());
00177 refreshAll();
00178 }
00179
00180 void
00181 BaseWindow::refreshAll() {
00182 std::for_each(basewindow_list.begin(),
00183 basewindow_list.end(),
00184 RefreshIt());
00185 }
00186
00187 #if defined(HAVE_SIGACTION) && defined(HAVE_SIGNAL_H)
00188 void
00189 BaseWindow::setTimeout(AlarmFunction* af, int sec) {
00190 alarm_fun = af;
00191 alarm(sec);
00192 }
00193
00194 void
00195 BaseWindow::suspendTimeout() {
00196 alarm(0);
00197 }
00198 #endif // defined(HAVE_SIGACTION) && defined(HAVE_SIGNAL_H)
00199
00200
00201
00202
00203 BaseWindow::BaseWindow() {
00204 BaseWindow::registerBaseWindow(this);
00205 }
00206
00207 BaseWindow::~BaseWindow() {
00208 BaseWindow::unregisterBaseWindow(this);
00209 }