/******************************** * * To compile: * * cc -o mapview mapview.c HGLfuncs.c Alloc.c ChooseFile.c * -lxview -lolgx -lX11 * ********************************/ #define POS2(array, i, j) (array[2*(i)+(j)]) #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifndef _GLOBAL_DEFS_H #include "global_defs.h" #define _GLOBAL_DEFS_H #endif #define min_pbl 1 #define max_pbl 15 #define min_scale 1 #define max_scale 1000 #define min_lwidth 1 #define max_lwidth 5 #define margin 100 #define WHITE 15 #define BLACK 8 #define RED 3 #define MASK_S2 5 #define MASK_S1 7 #define MASK_S0 10 Frame frame, prop_subframe; Canvas canvas; Xv_Window paint_win; Display *display; GC gc; Window xwin; Cms cms; Scrollbar h_scrollbar; Panel_item scale_slider, pbl_slider, lwidth_slider, color_chooser; Menu color_menu; int pbl = 10; int scale = 2; int lwidth = 2; int line_space= 12; char FROM_RESIZE = 'F'; int max_dots = 1000; /* This value will be dynamically assigned. * It is used to decide the paint window size. */ int drawarea_min_y, drawarea_max_y; unsigned long *colors; char clear_mark = 'F'; int mark_x=0; /* record the x,y of the paint window, */ int mark_y=0; /* not the canvas or the view window. */ int set_offset;/* The offset of the sequences being displayed. */ int save_for_mark_y; /* wrapping up. */ int canvas_h, line_p_page; typedef struct { char name[32]; int direction, strandedness, size, max_size; int orig_strand, orig_direction; int *dots; /* Dynamic 2D array. */ } INFO; INFO *info; int info_size; /* synchronization. */ char Lsync_fname[128]; char Lsync_YesNo = 'N'; /*Location synchronization Yes or No. */ char Csync_fname[128]; char Csync_YesNo = 'N'; /*Color synchronization Yes or No. */ main(argc, argv) int argc; char *argv[]; { Panel panel; int LoadHGLData(); extern exit_proc(); extern scale_proc(); extern pbl_proc(); extern footer_proc(); extern canvas_repaint_proc(); extern canvas_resize_proc(); extern Frame load_file(); extern Load(); extern Lsync_proc(); /* extern Csync_proc();*/ extern show_prop_frame(); extern lwidth_proc(); extern l_arrow(), r_arrow(); int i; static Xv_singlecolor cms_colors[] = { {0,128,0}, {255,192,0}, {255,0,255}, {225,0,0}, {0,192,192}, {0,192,0}, /* green */ {0,0,255}, {128,0,255}, /* purple */ {0,0,0}, {36,36,36}, {72,72,72}, {109,109,109}, {145,145,145}, {182,182,182}, {218,218,218}, {255,255,255} }; char filename[128]; FILE *fp; Rect *rect; /* malloc_debug(2); */ for(i = 1; imax_scale || scalemax_pbl || pbl1) { xv_set(frame,FRAME_LABEL, filename, NULL); rect = (Rect *)xv_get(canvas,CANVAS_VIEWABLE_RECT,paint_win); XClearArea(display, xwin, rect->r_left, rect->r_top, rect->r_width, rect->r_height, 0); if((set_offset = LoadHGLData(filename)) == -1) { exit(1); } } /* line_p_page = (canvas_h -line_space + pbl/2) / line_space; */ xv_main_loop(frame); } /*** * * LoadHGLData() reads HGL format data from fp_name, stores * the information in a global struct array 'info[]'. Return minumn * offset if successful, -1 if anything is wrong. * ***/ int LoadHGLData(name_str) char *name_str; { Sequence *tSeq; int iSeq, iSeg; int dot_cnt; int min_offset = INT_MAX; FILE *fp_fname; static int info_max_size = 0; if(strcmp(name_str, "") == 0) return -1; if((fp_fname = fopen(name_str,"r")) == NULL) { fprintf(stderr,"File not found: %s\n", name_str); exit(1); } max_dots = 1000; mark_x = mark_y = 0; iSeq = 0; tSeq = (Sequence *)Calloc(1, sizeof(Sequence)); if(info_max_size == 0) { info_max_size = 256; info = (INFO *)Calloc(info_max_size, sizeof(INFO)); } while(ReadRecord(fp_fname, tSeq) != -1) { SeqNormal(tSeq); if(iSeq == info_max_size) { info_max_size *= 2; info = (INFO *)Realloc(info, sizeof(INFO)*info_max_size); } strcpy(info[iSeq].name, tSeq->name); info[iSeq].direction = tSeq->direction; info[iSeq].strandedness = tSeq->strandedness; info[iSeq].orig_strand = tSeq->orig_strand; info[iSeq].orig_direction = tSeq->orig_direction; if(tSeq->orig_strand == 2) info[iSeq].orig_direction *= -1; min_offset = MIN(min_offset, tSeq->offset); max_dots = MAX(max_dots, tSeq->offset+tSeq->seqlen); if(info[iSeq].max_size == 0) { info[iSeq].max_size = 8; info[iSeq].dots=(int *)Calloc(info[iSeq].max_size*2, sizeof(int)); } iSeg = 0; POS2(info[iSeq].dots, iSeg, 0) = tSeq->offset; dot_cnt = 0; while(dot_cnt < tSeq->seqlen) { if(tSeq->c_elem[dot_cnt] != '-' && (tSeq->c_elem[dot_cnt+1] == '-' || dot_cnt+1 == tSeq->seqlen)) { POS2(info[iSeq].dots, iSeg++, 1) = tSeq->offset+dot_cnt; if(iSeg == info[iSeq].max_size) { info[iSeq].max_size *= 2; info[iSeq].dots = (int *)Realloc(info[iSeq].dots, sizeof(int)*2*info[iSeq].max_size); } } else if(tSeq->c_elem[dot_cnt] == '-' && tSeq->c_elem[dot_cnt+1] != '-') { POS2(info[iSeq].dots, iSeg, 0) = tSeq->offset + dot_cnt+1; } dot_cnt++; } info[iSeq].size = iSeg; iSeq++; } info_size = iSeq; fclose(fp_fname); FreeRecord(&tSeq); if (min_offset != 0) { max_dots -= min_offset; for(iSeq = 0; iSeqr_top; drawarea_max_y = drawarea_min_y + rect->r_height; } /* else: this is to redraw the cleared area. * drawarea_min_y and drawarea_max_y have been set by * the caller procedure, so don't reset they. */ /* * Set drawarea_min_x, drawarea_max_x. */ rect=(Rect *)xv_get(canvas,CANVAS_VIEWABLE_RECT,paint_win); drawarea_min_x = rect->r_left -1; drawarea_max_x = rect->r_left + rect->r_width; canvas_h = rect->r_height; y = 0; for(iSeq = 0; iSeq canvas_h) ? line_space : y + line_space; /* if(info[iSeq].orig_strand == 1) XSetForeground(display,gc,colors[MASK_S1]); else if(info[iSeq].orig_strand == 2 ) XSetForeground(display,gc,colors[MASK_S2]); else */ XSetForeground(display,gc,colors[MASK_S0]); /*if(info[iSeq].direction == -1 || info[iSeq].direction == 2 )*/ if(info[iSeq].orig_direction == -1) { l_arrow(lwidth, info[iSeq].orig_strand, POS2(info[iSeq].dots,0,0)/scale,y); } else if( info[iSeq].orig_direction == 1 ) { r_arrow(lwidth, info[iSeq].orig_strand, POS2(info[iSeq].dots, info[iSeq].size -1, 1)/scale,y); } for(iSeg=0; iSeg= drawarea_min_x && drawarea_min_y <= y && y <= drawarea_max_y) { for(i=0; i last_Lsync_time) { Lsync_fp = fopen(Lsync_fname, "r"); loc_name[0] = '\0'; while(fgets(line, 256, Lsync_fp) != NULL) { if(strncmp(line, "Col:", 4) == 0) loc_col = atoi(line+4); else if(strncmp(line, "SeqID:", 6) == 0) { strcpy(loc_name, line+6); loc_name[strlen(loc_name)-1] = '\0'; } } fclose(Lsync_fp); if(loc_name[0] == ' ' || loc_col == INT_MAX) { fprintf(stderr, "Bad status file.\n"); } else { iSeq = 0; while(iSeqr_width/2, (int)xv_get(h_scrollbar, SCROLLBAR_OBJECT_LENGTH) - (int)xv_get(canvas, XV_WIDTH))), NULL); last_Lsync_time = stbuf.st_mtime; } } } } } else if(event_id(event) == LOC_WINEXIT) { win_refuse_kbd_focus(canvas); /* win_refuse_kbd_focus(paint_win); */ if(Lsync_YesNo == 'Y') { /* update the status file. */ ii = 0; while(ii<20 && (Lsync_fp = fopen(Lsync_fname, "r+")) == NULL) { ii++; } if(ii == 20) { fprintf(stderr, "Can't open status file for updating: %s\n", Lsync_fname); } else { char *temp_file; int file_maxlen = 256, file_len = 0; temp_file = (char *)Calloc(file_maxlen, 1); while(fgets(line, 256, Lsync_fp) != NULL) { if(strncmp(line, "Col:", 4) == 0) { sprintf(line, "Col:%d\n", mark_x / scale); } else if(strncmp(line, "SeqID:", 6) == 0) { sprintf(line, "SeqID:%s\n", info[print_line-1].name); } file_len += strlen(line); if(file_len+1 >=file_maxlen) { file_maxlen *= 2; temp_file = (char *)Realloc(temp_file, file_maxlen); } strcat(temp_file , line); } fseek(Lsync_fp, 0L, 0); fprintf(Lsync_fp, "%s", temp_file); Cfree(temp_file); } fclose(Lsync_fp); } } if (event_is_down(event)) { if(event_action(event)==ACTION_SELECT) { mark_x = event_x(event)*scale + 0.5*scale; mark_y = event_y(event); need_to_paint = 'T'; } else if(event_is_key_right(event) || event_is_ascii(event)) { int return_int; return_int = XLookupString(event->ie_xevent,/*not used */ return_str, /*not used*/ return_len, /*not used*/ &keysym,NULL ); switch(keysym) { case XK_F31: /* center, key 5 on the right keyboard. */ rect = (Rect *) xv_get(canvas,CANVAS_VIEWABLE_RECT,paint_win); (void)xv_set(h_scrollbar, SCROLLBAR_VIEW_START, MAX(0, MIN(mark_x/scale - rect->r_width/2, (int)xv_get(h_scrollbar, SCROLLBAR_OBJECT_LENGTH) - (int)xv_get(canvas, XV_WIDTH))), NULL); break; case XK_F27: /* the home key. */ (void)xv_set(h_scrollbar, SCROLLBAR_VIEW_START,0, NULL); break; case XK_Left: if(mark_x - scale >1) mark_x -= scale; need_to_paint = 'T'; break; case XK_Right: mark_x += scale; need_to_paint = 'T'; break; case XK_Up: if (mark_y>= 2*line_space - pbl/2) mark_y -= line_space; else mark_y = line_p_page*line_space + lwidth; need_to_paint = 'T'; break; case XK_Down: if((mark_y - 2*line_space+pbl/2)/line_space +1 POS2(info[iSeq].dots,iSeg,1)) { accu_pos += POS2(info[iSeq].dots,iSeg,1) - POS2(info[iSeq].dots, iSeg ,0)+1; iSeg++; } else if(mark_x>= POS2(info[iSeq].dots,iSeg,0)) { if(position != INT_MIN) { /* ambiguous location. *** Set Foreground?? */ sprintf(buf, "Mouse location: Line = ? Position = ? Column = %d", set_offset + mark_x + 1 ); xv_set(frame,FRAME_LEFT_FOOTER, buf, NULL); xv_set(frame,FRAME_RIGHT_FOOTER,"Sequence: ",NULL); return XV_OK; } position = accu_pos + mark_x - POS2(info[iSeq].dots, iSeg, 0) + 1; print_line = iSeq+1; break; } else { break; } } iSeq += line_p_page; } if(position != INT_MIN) { sprintf(buf, "Mouse location: Line = %d Position = %d Column = %d", print_line, position, set_offset + mark_x + 1 ); xv_set(frame,FRAME_LEFT_FOOTER, buf, NULL); sprintf(buf,"Sequence: %s\n",info[print_line-1].name); save_for_mark_y = print_line; } else { sprintf(buf, "Mouse location: Line = Position = Column = %d", set_offset+mark_x+1); xv_set(frame,FRAME_LEFT_FOOTER, buf, NULL); sprintf(buf,"Sequence: \n"); } xv_set(frame,FRAME_RIGHT_FOOTER, buf, NULL); } return XV_OK; } Load(item,event) Panel_item item; Event *event; { extern Frame load_file(); /* rtm 18.III.98 */ (void)load_file(frame,300,150,NULL); return XV_OK; } canvas_resize_proc(canvas, canvas_width, canvas_height) Canvas canvas; int canvas_width, canvas_height; { int tt; FROM_RESIZE = 'T'; canvas_h = canvas_height; line_p_page = (canvas_h -line_space + pbl/2) / line_space; tt = save_for_mark_y % line_p_page; if(tt == 0) tt = line_p_page; mark_y = tt*line_space; } scale_proc(item, i_scale, event) Panel_item item; int i_scale; Event *event; { scale = i_scale; (void)xv_set(h_scrollbar, SCROLLBAR_OBJECT_LENGTH, MAX((int)xv_get(canvas, XV_WIDTH), max_dots/scale+margin), SCROLLBAR_VIEW_START, MAX(0, MIN(mark_x/scale - 100, max_dots/scale+margin - (int)xv_get(canvas, XV_WIDTH))), NULL); (void)xv_set(paint_win, XV_WIDTH, MAX((int)xv_get(canvas,XV_WIDTH),max_dots/scale+margin), NULL); XClearWindow(display, xwin); canvas_repaint_proc(canvas,paint_win,display, xwin, NULL); return XV_OK; } pbl_proc(item, i_pbl, event) Panel_item item; int i_pbl; Event *event; { int tt; pbl = i_pbl; line_space = pbl + lwidth; line_p_page = (canvas_h -line_space + pbl/2) / line_space; tt = save_for_mark_y % line_p_page; if(tt == 0) tt = line_p_page; mark_y = tt*line_space; XClearWindow(display, xwin); canvas_repaint_proc(canvas,paint_win,display, xwin, NULL); return XV_OK; } lwidth_proc(item, i_lw, event) Panel_item item; int i_lw; Event *event; { int tt; lwidth = i_lw; line_space = pbl + lwidth; line_p_page = (canvas_h -line_space + pbl/2) / line_space; tt = save_for_mark_y % line_p_page; if(tt == 0) tt = line_p_page; mark_y = tt*line_space; XClearWindow(display, xwin); canvas_repaint_proc(canvas,paint_win,display, xwin, NULL); return XV_OK; } exit_proc(item, event) Panel_item item; Event *event; { if (event_action(event) == ACTION_SELECT) { xv_destroy_safe(frame); return(XV_OK); } else return(XV_ERROR); } Lsync_proc(item, value, event) Panel_item item; int value; Event *event; { if(value == 0) Lsync_YesNo = 'N'; else if(value == 1) Lsync_YesNo = 'Y'; else fprintf(stderr, "Lsync_proc: value= %d\n", value); } show_prop_frame(item, event) Frame item; Event *event; { xv_set(prop_subframe, XV_SHOW, TRUE, NULL); } r_arrow(size, strand, loc_x, loc_y) int size, strand, loc_x, loc_y; { int ii; if(size == 1) { if(strand < 2) XDrawLine(display,xwin,gc,loc_x, loc_y,loc_x-2,loc_y-2); if(strand == 0 || strand == 2) XDrawLine(display,xwin,gc,loc_x, loc_y,loc_x-2,loc_y+2); } /* draw the wings. */ for(ii=1; ii <= size/2+1; ii++) { if(strand < 2) XDrawLine(display,xwin,gc, loc_x-ii, loc_y-ii, loc_x-ii, loc_y-1); if(strand == 0 || strand == 2) XDrawLine(display,xwin,gc, loc_x-ii, loc_y+size-1+ii, loc_x-ii, loc_y+size); /* actually, loc_y+size-1+1.*/ } /* draw the tip. */ for(ii = 1; strand == 0 && ii < (size+1)/2; ii++) { XDrawLine(display,xwin,gc, loc_x+ii, loc_y+ii, loc_x+ii, loc_y+size-1-ii); } for(ii=1; strand==1 && ii < size; ii++) { XDrawLine(display,xwin,gc, loc_x+ii, loc_y+ii, loc_x+ii, loc_y+size-1); } for(ii=1; strand==2 && ii < size; ii++) { XDrawLine(display,xwin,gc, loc_x+ii, loc_y, loc_x+ii, loc_y+size-1-ii); } } l_arrow(size, strand, loc_x, loc_y) int size, strand, loc_x, loc_y; { int ii; if(size == 1) { if(strand < 2) XDrawLine(display,xwin,gc,loc_x, loc_y,loc_x+2,loc_y-2); if(strand == 0 || strand == 2) XDrawLine(display,xwin,gc,loc_x, loc_y,loc_x+2,loc_y+2); } /* draw the wings. */ for(ii=1; ii <= size/2+1; ii++) { if(strand < 2) XDrawLine(display,xwin,gc, loc_x+ii, loc_y-ii, loc_x+ii, loc_y-1); if(strand == 0 || strand == 2) XDrawLine(display,xwin,gc, loc_x+ii, loc_y+size-1+ii, loc_x+ii, loc_y+size); /* actually, loc_y+size-1+1.*/ } /* draw the tip. */ for(ii = 1; strand == 0 && ii < (size+1)/2; ii++) { XDrawLine(display,xwin,gc, loc_x-ii, loc_y+ii, loc_x-ii, loc_y+size-1-ii); } for(ii=1; strand==1 && ii < size; ii++) { XDrawLine(display,xwin,gc, loc_x-ii, loc_y+ii, loc_x-ii, loc_y+size-1); } for(ii=1; strand==2 && ii < size; ii++) { XDrawLine(display,xwin,gc, loc_x-ii, loc_y, loc_x-ii, loc_y+size-1-ii); } } cross(size, loc_x, loc_y) int size, loc_x, loc_y; { int ii; if(size == 1) { XDrawLine(display,xwin,gc, loc_x-2,loc_y, loc_x+2,loc_y); XDrawLine(display,xwin,gc, loc_x, loc_y-2,loc_x, loc_y+2); } else if(size == 2) { for(ii=0; ii<2; ii++) { XDrawLine(display,xwin,gc,loc_x-2,loc_y+ii,loc_x+3,loc_y+ii); XDrawLine(display,xwin,gc,loc_x+ii,loc_y-2,loc_x+ii,loc_y+3); } } else { for(ii= -1; ii<2; ii++) { XDrawLine(display,xwin,gc,loc_x-4,loc_y+ii,loc_x+4,loc_y+ii); XDrawLine(display,xwin,gc,loc_x+ii,loc_y-4,loc_x+ii,loc_y+4); } } }