]> git.donarmstrong.com Git - samtools.git/blob - bam_tview_curses.c
cont
[samtools.git] / bam_tview_curses.c
1 #undef _HAVE_CURSES
2
3 #if _CURSES_LIB == 0
4 #elif _CURSES_LIB == 1
5 #include <curses.h>
6 #ifndef NCURSES_VERSION
7 #warning "_CURSES_LIB=1 but NCURSES_VERSION not defined; tview is NOT compiled"
8 #else
9 #define _HAVE_CURSES
10 #endif
11 #elif _CURSES_LIB == 2
12 #include <xcurses.h>
13 #define _HAVE_CURSES
14 #else
15 #warning "_CURSES_LIB is not 0, 1 or 2; tview is NOT compiled"
16 #endif
17
18
19 #include "bam_tview.h"
20
21 #ifdef _HAVE_CURSES
22
23
24
25 typedef struct CursesTview {
26         tview_t view;
27         WINDOW *wgoto, *whelp;
28         } curses_tview_t;
29
30
31
32
33 #define FROM_TV(ptr) ((curses_tview_t*)ptr)
34
35 static void curses_destroy(tview_t* base)
36         {
37         curses_tview_t* tv=(curses_tview_t*)base;
38
39         
40         delwin(tv->wgoto); delwin(tv->whelp);
41         endwin();
42
43         base_tv_destroy(base);
44         
45         free(tv);
46         }
47
48 /*
49  void (*my_mvprintw)(struct AbstractTview* ,int,int,const char*,...);
50     void (*my_)(struct AbstractTview*,int,int,int);
51     void (*my_attron)(struct AbstractTview*,int);
52     void (*my_attroff)(struct AbstractTview*,int);
53     void (*my_clear)(struct AbstractTview*);
54     int (*my_colorpair)(struct AbstractTview*,int);
55 */
56
57 static void curses_mvprintw(struct AbstractTview* tv,int y ,int x,const char* fmt,...)
58         {
59         unsigned int size=tv->mcol+2;
60         char* str=malloc(size);
61         if(str==0) exit(EXIT_FAILURE);
62         va_list argptr;
63         va_start(argptr, fmt);
64         vsnprintf(str,size, fmt, argptr);
65         va_end(argptr);
66         mvprintw(y,x,str);
67         free(str);
68         }
69
70 static void curses_mvaddch(struct AbstractTview* tv,int y,int x,int ch)
71         {
72         mvaddch(y,x,ch);
73         }
74         
75 static void curses_attron(struct AbstractTview* tv,int flag)
76     {
77     attron(flag);
78     }
79 static void curses_attroff(struct AbstractTview* tv,int flag)
80     {
81     attroff(flag);
82     }
83 static void curses_clear(struct AbstractTview* tv)
84     {
85     clear();
86     }
87     
88 static int curses_colorpair(struct AbstractTview* tv,int flag)
89     {
90     return COLOR_PAIR(flag);
91     }
92
93 static int curses_drawaln(struct AbstractTview* tv, int tid, int pos)
94     {
95     return base_draw_aln(tv,  tid, pos);
96     }
97
98
99
100 static void tv_win_goto(curses_tview_t *tv, int *tid, int *pos)
101         {
102         char str[256], *p;
103         int i, l = 0;
104         tview_t *base=(tview_t*)tv;
105         wborder(tv->wgoto, '|', '|', '-', '-', '+', '+', '+', '+');
106         mvwprintw(tv->wgoto, 1, 2, "Goto: ");
107         for (;;) {
108                 int c = wgetch(tv->wgoto);
109                 wrefresh(tv->wgoto);
110                 if (c == KEY_BACKSPACE || c == '\010' || c == '\177') {
111                         if(l > 0) --l;
112                 } else if (c == KEY_ENTER || c == '\012' || c == '\015') {
113                         int _tid = -1, _beg, _end;
114                         if (str[0] == '=') {
115                                 _beg = strtol(str+1, &p, 10) - 1;
116                                 if (_beg > 0) {
117                                         *pos = _beg;
118                                         return;
119                                 }
120                         } else {
121                                 bam_parse_region(base->header, str, &_tid, &_beg, &_end);
122                                 if (_tid >= 0) {
123                                         *tid = _tid; *pos = _beg;
124                                         return;
125                                 }
126                         }
127                 } else if (isgraph(c)) {
128                         if (l < TV_MAX_GOTO) str[l++] = c;
129                 } else if (c == '\027') l = 0;
130                 else if (c == '\033') return;
131                 str[l] = '\0';
132                 for (i = 0; i < TV_MAX_GOTO; ++i) mvwaddch(tv->wgoto, 1, 8 + i, ' ');
133                 mvwprintw(tv->wgoto, 1, 8, "%s", str);
134         }
135 }
136
137
138
139
140 static void tv_win_help(curses_tview_t *tv) {
141         int r = 1;
142         tview_t* base=(tview_t*)base;
143         WINDOW *win = tv->whelp;
144         wborder(win, '|', '|', '-', '-', '+', '+', '+', '+');
145         mvwprintw(win, r++, 2, "        -=-    Help    -=- ");
146         r++;
147         mvwprintw(win, r++, 2, "?          This window");
148         mvwprintw(win, r++, 2, "Arrows     Small scroll movement");
149         mvwprintw(win, r++, 2, "h,j,k,l    Small scroll movement");
150         mvwprintw(win, r++, 2, "H,J,K,L    Large scroll movement");
151         mvwprintw(win, r++, 2, "ctrl-H     Scroll 1k left");
152         mvwprintw(win, r++, 2, "ctrl-L     Scroll 1k right");
153         mvwprintw(win, r++, 2, "space      Scroll one screen");
154         mvwprintw(win, r++, 2, "backspace  Scroll back one screen");
155         mvwprintw(win, r++, 2, "g          Go to specific location");
156         mvwprintw(win, r++, 2, "m          Color for mapping qual");
157         mvwprintw(win, r++, 2, "n          Color for nucleotide");
158         mvwprintw(win, r++, 2, "b          Color for base quality");
159         mvwprintw(win, r++, 2, "c          Color for cs color");
160         mvwprintw(win, r++, 2, "z          Color for cs qual");
161         mvwprintw(win, r++, 2, ".          Toggle on/off dot view");
162         mvwprintw(win, r++, 2, "s          Toggle on/off ref skip");
163         mvwprintw(win, r++, 2, "r          Toggle on/off rd name");
164         mvwprintw(win, r++, 2, "N          Turn on nt view");
165         mvwprintw(win, r++, 2, "C          Turn on cs view");
166         mvwprintw(win, r++, 2, "i          Toggle on/off ins");
167         mvwprintw(win, r++, 2, "q          Exit");
168         r++;
169         mvwprintw(win, r++, 2, "Underline:      Secondary or orphan");
170         mvwprintw(win, r++, 2, "Blue:    0-9    Green: 10-19");
171         mvwprintw(win, r++, 2, "Yellow: 20-29   White: >=30");
172         wrefresh(win);
173         wgetch(win);
174 }
175
176 static int curses_underline(tview_t* tv)
177         {
178         return A_UNDERLINE;
179         }
180         
181 static int curses_loop(tview_t* tv)
182         {
183         int tid, pos;
184         curses_tview_t *CTV=(curses_tview_t *)tv;
185         tid = tv->curr_tid; pos = tv->left_pos;
186         while (1) {
187                 int c = getch();
188                 switch (c) {
189                         case '?': tv_win_help(CTV); break;
190                         case '\033':
191                         case 'q': goto end_loop;
192                         case '/': 
193                         case 'g': tv_win_goto(CTV, &tid, &pos); break;
194                         case 'm': tv->color_for = TV_COLOR_MAPQ; break;
195                         case 'b': tv->color_for = TV_COLOR_BASEQ; break;
196                         case 'n': tv->color_for = TV_COLOR_NUCL; break;
197                         case 'c': tv->color_for = TV_COLOR_COL; break;
198                         case 'z': tv->color_for = TV_COLOR_COLQ; break;
199                         case 's': tv->no_skip = !tv->no_skip; break;
200                         case 'r': tv->show_name = !tv->show_name; break;
201                         case KEY_LEFT:
202                         case 'h': --pos; break;
203                         case KEY_RIGHT:
204                         case 'l': ++pos; break;
205                         case KEY_SLEFT:
206                         case 'H': pos -= 20; break;
207                         case KEY_SRIGHT:
208                         case 'L': pos += 20; break;
209                         case '.': tv->is_dot = !tv->is_dot; break;
210                         case 'N': tv->base_for = TV_BASE_NUCL; break;
211                         case 'C': tv->base_for = TV_BASE_COLOR_SPACE; break;
212                         case 'i': tv->ins = !tv->ins; break;
213                         case '\010': pos -= 1000; break;
214                         case '\014': pos += 1000; break;
215                         case ' ': pos += tv->mcol; break;
216                         case KEY_UP:
217                         case 'j': --tv->row_shift; break;
218                         case KEY_DOWN:
219                         case 'k': ++tv->row_shift; break;
220                         case KEY_BACKSPACE:
221                         case '\177': pos -= tv->mcol; break;
222                         case KEY_RESIZE: getmaxyx(stdscr, tv->mrow, tv->mcol); break;
223                         default: continue;
224                 }
225                 if (pos < 0) pos = 0;
226                 if (tv->row_shift < 0) tv->row_shift = 0;
227                 tv->my_drawaln(tv, tid, pos);
228         }
229 end_loop:
230         return 0;
231 }
232
233
234
235
236 tview_t* curses_tv_init(const char *fn, const char *fn_fa, const char *samples)
237         {
238         curses_tview_t *tv = (curses_tview_t*)calloc(1, sizeof(curses_tview_t));
239         tview_t* base=(tview_t*)tv;
240         if(tv==0)
241                 {
242                 fprintf(stderr,"Calloc failed\n");
243                 return 0;
244                 }
245         
246         base_tv_init(base,fn,fn_fa,samples);
247         /* initialize callbacks */
248 #define SET_CALLBACK(fun) base->my_##fun=curses_##fun;
249         SET_CALLBACK(destroy);
250         SET_CALLBACK(mvprintw);
251         SET_CALLBACK(mvaddch);
252         SET_CALLBACK(attron);
253         SET_CALLBACK(attroff);
254         SET_CALLBACK(clear);
255         SET_CALLBACK(colorpair);
256         SET_CALLBACK(drawaln);
257         SET_CALLBACK(loop);
258         SET_CALLBACK(underline);
259 #undef SET_CALLBACK
260
261         initscr();
262         keypad(stdscr, TRUE);
263         clear();
264         noecho();
265         cbreak();
266         
267         getmaxyx(stdscr, base->mrow, base->mcol);
268         tv->wgoto = newwin(3, TV_MAX_GOTO + 10, 10, 5);
269         tv->whelp = newwin(29, 40, 5, 5);
270         
271         start_color();
272         init_pair(1, COLOR_BLUE, COLOR_BLACK);
273         init_pair(2, COLOR_GREEN, COLOR_BLACK);
274         init_pair(3, COLOR_YELLOW, COLOR_BLACK);
275         init_pair(4, COLOR_WHITE, COLOR_BLACK);
276         init_pair(5, COLOR_GREEN, COLOR_BLACK);
277         init_pair(6, COLOR_CYAN, COLOR_BLACK);
278         init_pair(7, COLOR_YELLOW, COLOR_BLACK);
279         init_pair(8, COLOR_RED, COLOR_BLACK);
280         init_pair(9, COLOR_BLUE, COLOR_BLACK);
281         return base;
282         }
283
284
285 #else // #ifdef _HAVE_CURSES
286 #include <stdio.h>
287 #warning "No curses library is available; tview with curses is disabled."
288
289 extern tview_t* text_tv_init(const char *fn, const char *fn_fa, const char *samples);
290
291 tview_t* curses_tv_init(const char *fn, const char *fn_fa, const char *samples)
292         {
293         return text_tv_init(fn,fn_fa,samples);
294         }
295 #endif // #ifdef _HAVE_CURSES
296
297