Go to the documentation of this file.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_STDIO_H
00033 # include <stdio.h>
00034 #endif
00035
00036 #ifdef HAVE_ALGORITHM
00037 # include <algorithm>
00038 #endif
00039
00040 #ifdef HAVE_STRING
00041 # include <string>
00042 #endif
00043
00044 using namespace YAPET::UI;
00045
00046 class RemoveByAddr {
00047 private:
00048 const BaseWindow* ptr;
00049
00050 public:
00051 inline RemoveByAddr (const BaseWindow* p) : ptr (p) {}
00052 inline bool operator() (const BaseWindow* p) const {
00053 if (ptr == p)
00054 return true;
00055
00056 return false;
00057 }
00058 };
00059
00060 class DeleteIt {
00061 public:
00062 inline void operator() (BaseWindow* p) const {
00063 if (p != NULL)
00064 delete p;
00065 }
00066 };
00067
00068 class ResizeIt {
00069 public:
00070 inline void operator() (BaseWindow* p) const {
00071 p->resize();
00072 }
00073 };
00074
00075 class RefreshIt {
00076 public:
00077 inline void operator() (BaseWindow* p) const {
00078 p->refresh();
00079 }
00080 };
00081
00082
00083
00084
00085 std::list<BaseWindow*> BaseWindow::basewindow_list = std::list<BaseWindow*>();
00086 BaseWindow::AlarmFunction* BaseWindow::alarm_fun = NULL;
00087
00088 #if defined(HAVE_SIGACTION) && defined(HAVE_SIGNAL_H)
00089 void
00090 BaseWindow::sig_handler (int signo) {
00091 switch (signo) {
00092 case SIGALRM:
00093
00094 if (alarm_fun != NULL)
00095 alarm_fun->process (signo);
00096
00097 break;
00098 case SIGHUP:
00099 case SIGINT:
00100 case SIGQUIT:
00101 case SIGTERM:
00102 case SIGKILL:
00103 deleteAll();
00104 endCurses();
00105 abort();
00106 }
00107 }
00108
00109 void
00110 BaseWindow::init_signal() {
00111 sigset_t sigset;
00112 sigemptyset (&sigset);
00113
00114 sigprocmask (SIG_SETMASK, NULL, &sigset);
00115
00116 sigaddset (&sigset, SIGALRM);
00117 sigaddset (&sigset, SIGTERM);
00118 sigaddset (&sigset, SIGKILL);
00119 sigaddset (&sigset, SIGQUIT);
00120 sigaddset (&sigset, SIGINT);
00121 sigaddset (&sigset, SIGHUP);
00122 sigprocmask (SIG_UNBLOCK, &sigset, NULL);
00123 struct sigaction sa;
00124 sigemptyset (&sa.sa_mask);
00125 sa.sa_flags = 0;
00126 sa.sa_handler = BaseWindow::sig_handler;
00127 sigaction (SIGALRM, &sa, NULL);
00128 sigaction (SIGTERM, &sa, NULL);
00129 sigaction (SIGKILL, &sa, NULL);
00130 sigaction (SIGQUIT, &sa, NULL);
00131 sigaction (SIGINT, &sa, NULL);
00132 sigaction (SIGHUP, &sa, NULL);
00133 }
00134 #endif // defined(HAVE_SIGACTION) && defined(HAVE_SIGNAL_H)
00135
00136 void
00137 BaseWindow::initCurses() throw(UIException) {
00138 initscr();
00139
00140 int max_y, max_x;
00141 getmaxyx (stdscr, max_y, max_x);
00142 if (max_y < MIN_Y ||
00143 max_x < MIN_X) {
00144 char msg[1024];
00145 ::snprintf(msg, 1024, _("Need at least a resolution of %dx%d."), MIN_X, MIN_Y);
00146 throw UIException(msg);
00147 }
00148
00149 raw();
00150 noecho();
00151 ::refresh();
00152 curs_set (0);
00153 keypad (stdscr, TRUE);
00154 YAPET::UI::Colors::initColors();
00155 init_signal();
00156 }
00157
00158 void
00159 BaseWindow::endCurses() {
00160 clear();
00161 ::refresh();
00162 endwin();
00163 }
00164
00165 void
00166 BaseWindow::registerBaseWindow (BaseWindow* r) {
00167 basewindow_list.push_back (r);
00168 }
00169
00170 void
00171 BaseWindow::unregisterBaseWindow (BaseWindow* r) {
00172 std::list<BaseWindow*>::iterator it =
00173 std::remove_if (basewindow_list.begin(),
00174 basewindow_list.end(),
00175 RemoveByAddr (r) );
00176 basewindow_list.erase (it, basewindow_list.end() );
00177 }
00178
00179 void
00180 BaseWindow::deleteAll() {
00181 std::for_each (basewindow_list.rbegin(),
00182 basewindow_list.rend(),
00183 DeleteIt() );
00184 }
00185
00186 void
00187 BaseWindow::resizeAll() {
00188 int max_x, max_y;
00189 getmaxyx (stdscr, max_y, max_x);
00190
00191 if (max_y < MIN_Y ||
00192 max_x < MIN_X) return;
00193
00194 std::for_each (basewindow_list.begin(),
00195 basewindow_list.end(),
00196 ResizeIt() );
00197 refreshAll();
00198 }
00199
00200 void
00201 BaseWindow::refreshAll() {
00202 std::for_each (basewindow_list.begin(),
00203 basewindow_list.end(),
00204 RefreshIt() );
00205 }
00206
00207 #if defined(HAVE_SIGACTION) && defined(HAVE_SIGNAL_H)
00208 void
00209 BaseWindow::setTimeout (AlarmFunction* af, int sec) {
00210 alarm_fun = af;
00211 alarm (sec);
00212 }
00213
00214 void
00215 BaseWindow::suspendTimeout() {
00216 alarm (0);
00217 }
00218 #endif // defined(HAVE_SIGACTION) && defined(HAVE_SIGNAL_H)
00219
00220
00221
00222
00223 BaseWindow::BaseWindow() {
00224 BaseWindow::registerBaseWindow (this);
00225 }
00226
00227 BaseWindow::~BaseWindow() {
00228 BaseWindow::unregisterBaseWindow (this);
00229 }