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