#include "cursesview.h" #include #include #include #include #define CURSESWIN_COUNT 3 // Global variable shared by all threads to say "finish current operation and go away" extern int end; // window updated by cursesUpdateSliceDump callback from "worker" thread, with a mutex for prevent fuzzy concurrent updates WINDOW *winUpdateSliceDump=NULL; static pthread_mutex_t ncursesWriteMutex = PTHREAD_MUTEX_INITIALIZER; // Helpers declaration (below the interesting code of this file) int cursesInit(WINDOW *wins[], PANEL *panels[], int count); void cursesUnInit(WINDOW *wins[], PANEL *panels[], int count); void cursesUpdateSliceDump(slices_evt_t *slicesEvt, slice_t *modifiedSlice); void print_in_middle(WINDOW *win, int starty, int startx, int width, char *string, chtype color); void makeWin(WINDOW **win, PANEL **panel, int h, int w, int y, int x, char title[]); void cursesMainLoop(slices_evt_t *slicesEvt) { WINDOW *wins[CURSESWIN_COUNT]; PANEL *panels[CURSESWIN_COUNT]; int ch, i; char str[2]; cursesInit(wins, panels, CURSESWIN_COUNT); wattron(wins[CURSESWIN_COUNT-1], COLOR_PAIR(4)); mvwprintw(wins[CURSESWIN_COUNT-1], 1, 0, "(F2 to Exit)"); // wattroff(wins[CURSESWIN_COUNT-1], COLOR_PAIR(4)); update_panels(); doupdate(); /* Enable worker listener */ //FIXME : check pointers ? winUpdateSliceDump=wins[1]; slicesEvt->eventListener=cursesUpdateSliceDump; while((ch = getch()) != KEY_F(2)) { pthread_mutex_lock(&ncursesWriteMutex); switch(ch) { case '1': case '2': case '3': str[0]=ch; str[1]='\0'; // int (ascii value+flags) to string i=strtol(str, (char **)NULL, 10); // string to real integer if (i>0 && i<=CURSESWIN_COUNT) { top_panel(panels[i-1]); update_panels(); } break; } doupdate(); pthread_mutex_unlock(&ncursesWriteMutex); } pthread_mutex_lock(&(slicesEvt->eventListenerMutex)); slicesEvt->eventListener=NULL; pthread_mutex_unlock(&(slicesEvt->eventListenerMutex)); end=1; cursesUnInit(wins, panels, CURSESWIN_COUNT); } int cursesInit(WINDOW *wins[], PANEL *panels[], int count) { int screenH, screenW; /* Initialize curses */ initscr(); start_color(); raw(); keypad(stdscr, TRUE); noecho(); /* Initialize all the colors */ init_pair(1, COLOR_WHITE, COLOR_BLACK); init_pair(2, COLOR_WHITE, COLOR_BLUE); init_pair(3, COLOR_BLUE, COLOR_BLACK); init_pair(4, COLOR_CYAN, COLOR_BLACK); /* Initialize windows and panels */ getmaxyx(stdscr, screenH, screenW); if ( screenH < 8 || screenW < 40 ) return 1; makeWin(wins+0, panels+0, 3 , screenW, 0 , 0, "Menu"); makeWin(wins+1, panels+1, screenH-6 , screenW, 3 , 0, "Main Win"); makeWin(wins+2, panels+2, 2 , screenW, screenH-3 , 0, "Commands"); /* Set up the user pointers to the next panel set_panel_userptr(panels[0], panels[1]); set_panel_userptr(panels[1], panels[2]); set_panel_userptr(panels[2], panels[0]); */ /* Update the stacking order. 2nd panel will be on top */ update_panels(); return 0; } void cursesUnInit(WINDOW *wins[], PANEL *panels[], int count) { int i; for (i=0;idata, &blockSize, charCount, slicesEvt->data->min, slicesEvt->data->max); if (toPrint != NULL) { attron(COLOR_PAIR(4)); mvwprintw(winUpdateSliceDump, 1, 0, toPrint); // attroff(COLOR_PAIR(4)); update_panels(); doupdate(); free(toPrint); } /* sprintf(toPrint, "%c - %p %p", strProgress[progress], slicesEvt, modifiedSlice); progress=(progress+1)%strlen(strProgress); */ pthread_mutex_unlock(&ncursesWriteMutex); } void print_in_middle(WINDOW *win, int starty, int startx, int width, char *string, chtype color) { int length, x, y; float temp; if(win == NULL) win = stdscr; getyx(win, y, x); if(startx != 0) x = startx; if(starty != 0) y = starty; if(width == 0) width = 80; length = strlen(string); temp = (width - length)/ 2; x = startx + (int)temp; wattron(win, color); mvwprintw(win, y, x, "%s", string); wattroff(win, color); refresh(); } void makeWin(WINDOW **win, PANEL **panel, int h, int w, int y, int x, char title[]) { int i; *win = newwin(h, w, y, x); mvwprintw(*win, 0, 0, "%s", title); mvwchgat(*win, 0, 0, -1, A_BOLD, 2, NULL); for(i=1;i