Logo Search packages:      
Sourcecode: tucnak2 version File versions  Download package

subwin.c

/*
    Tucnak - VHF contest log
    Copyright (C) 2002-2006  Ladislav Vaiz <ok1zia@nagano.cz>
    and authors of web browser Links 0.96

    This program is free software; you can redistribute it and/or                                                        
    modify it under the terms of the GNU General Public License                                                          
    version 2 as published by the Free Software Foundation.

*/


#include "header.h"

struct session *gses;

struct subwin *new_subwin(enum sw_type type, gchar *title,
         /* optional */ void (*enter)(void *,gchar *)){
    struct subwin *sw;

    sw = g_new0(struct subwin,1);
    
    sw->x = 1;
    sw->y = QSONR_HEIGHT;
    sw->w = term->x - 2;
    sw->h = term->y - QSONR_HEIGHT - 4 - cfg->loglines;
    if (aband) sw->h -= aband->spypeers->len;
    
    sw->hh = sw->h;
    sw->type = type;
    sw->title = g_strdup(title);
    sw->cur = -1;
    sw->maxlen = 1000;

    sw->kbd_func        = NULL;
    sw->mouse_func      = NULL;
    sw->redraw          = NULL;
    sw->check_bounds    = NULL;
    
    sw->ws.ws_col = sw->w;
    sw->ws.ws_row = sw->h-1;
    sw->ws.ws_xpixel = 0;
    sw->ws.ws_ypixel = 0;

    sw->read_fd =  -1;
    sw->write_fd = -1;
    
    sw->high = g_ptr_array_new();
    g_ptr_array_add(sw->high, g_strdup("<\\*[0-9a-zA-Z\\-]+\\*>"));
    
    if (sw->type == SWT_PIPE || sw->type == SWT_TALK){
        sw->il = g_new0(struct inputln,1);
        sw->il->term = term;
        sw->il->sw = sw;
        {
            struct event ev = {EV_INIT, 0,0,0};
            inputln_func(sw->il,&ev);
        }
        sw->il->x = sw->x;
        sw->il->y = sw->y + sw->h - 1;
        sw->il->l = sw->w;
        sw->il->enter = enter;
        sw->il->enterdata = sw;
        sw->h--;
    }

    if (sw->type == SWT_QSOS){
        sw->kbd_func        = sw_qsos_kbd_func;
        sw->mouse_func      = sw_qsos_mouse_func;
        sw->redraw          = sw_qsos_redraw;
        sw->check_bounds    = sw_qsos_check_bounds;
    }
    
    if (sw->type == SWT_LOG){
        sw->kbd_func        = sw_fifo_kbd_func;
        sw->mouse_func      = sw_fifo_mouse_func;
        sw->redraw          = sw_fifo_redraw;
        sw->check_bounds    = sw_fifo_check_bounds;
        sw->fifo            = glog;
    }

    if (sw->type == SWT_PIPE){
        /*sw->kbd_func        = sw_pipe_kbd_func;*/
        sw->kbd_func        = sw_fifo_kbd_func;
        sw->mouse_func      = sw_pipe_mouse_func;
        sw->redraw          = sw_pipe_redraw;
        sw->check_bounds    = sw_pipe_check_bounds;
        sw->il->allow_ctrlv     = 1;
        
        sw->lines           = g_ptr_array_new();
#ifdef HAVE_PTY_H        
        sw_pty_run(sw, "/bin/bash");
#else
        sw_pipe_run(sw, "/bin/bash");
#endif            
    }
    
    if (sw->type == SWT_TALK){
        sw->kbd_func        = sw_fifo_kbd_func;
        sw->mouse_func      = sw_fifo_mouse_func;
        sw->redraw          = sw_fifo_redraw;
        sw->check_bounds    = sw_fifo_check_bounds;
        sw->fifo            = gtalk;
        sw->il->enter       = sw_talk_enter;
        sw->il->enterdata   = sw;
        sw->il->allow_ctrlv = 1;
    }

    if (sw->type == SWT_DXC){
        sw->kbd_func        = sw_dxc_kbd_func;
        sw->mouse_func      = sw_dxc_mouse_func;
        sw->redraw          = sw_dxc_redraw;
        sw->check_bounds    = sw_dxc_check_bounds;
    }

    if (sw->type == SWT_SKED){
        sw->kbd_func        = sw_fifo_kbd_func;
        sw->mouse_func      = sw_fifo_mouse_func;
        sw->redraw          = sw_fifo_redraw;
        sw->check_bounds    = sw_fifo_check_bounds;
        sw->fifo            = gsked;
    }
    
    if (sw->type == SWT_UNFI){
        sw->kbd_func        = sw_unfi_kbd_func;
        sw->mouse_func      = sw_unfi_mouse_func;
        sw->redraw          = sw_unfi_redraw;
        sw->check_bounds    = sw_unfi_check_bounds;
        sw->fifo            = NULL; /* filled in sw_unfi* */
    }
    
    if (sw->type == SWT_STAT){
        sw->kbd_func        = sw_stat_kbd_func;
        sw->mouse_func      = sw_stat_mouse_func;
        sw->redraw          = sw_stat_redraw;
        sw->check_bounds    = sw_stat_check_bounds;
        sw->raise           = sw_stat_raise;
        sw->fifo            = NULL; /* filled in sw_stat* */
    }

    if (sw->type == SWT_MAP){
        sw->kbd_func        = sw_map_kbd_func;
        sw->mouse_func      = sw_map_mouse_func;
        sw->redraw          = sw_map_redraw;
        sw->check_bounds    = sw_map_check_bounds;
        sw->raise           = sw_map_raise;

#ifdef HAVE_SDL        
        if (sdl){
            sw->screen = SDL_CreateRGBSurface(SDL_SWSURFACE, sw->w*FONT_W, sw->h*FONT_H, sdl->bpp, 
                    sdl->screen->format->Rmask, sdl->screen->format->Gmask, sdl->screen->format->Gmask, 0);
            sw->screen_mutex = g_mutex_new();
            sw->zoom = 10000;
              /*  sw->zoom = 1000; */
            sw->gdirty = 1;
            map_update_layout(sw);
            map_update_qth(sw);
        }
#endif
    }
    
    sw->check_bounds(sw);
    g_ptr_array_add(gses->subwins, sw);
    
    return sw;
}

void free_subwins(){
    int i;

    for (i=gses->subwins->len-1;i>=0;i--){
        struct subwin *sw;

        sw=(struct subwin *)g_ptr_array_index(gses->subwins, i);
        free_subwin(sw);
    }
    g_ptr_array_free(gses->subwins, TRUE);
}

void free_subwin(struct subwin *sw){
    
    g_ptr_array_remove(gses->subwins, sw);
    
    if (sw->high) g_ptr_array_free_all(sw->high);
    if (sw->title) g_free(sw->title);
    if (sw->lines) g_ptr_array_free_all(sw->lines);
    if (sw->pid>0) sw_pipe_kill(sw);
    if (sw->write_fd>=0) set_handlers(sw->write_fd, NULL, NULL, NULL, CBA0);
    if (sw->read_fd>=0)  set_handlers(sw->read_fd, NULL, NULL, NULL, CBA0);
#ifdef HAVE_SDL    
    if (sw->screen) SDL_FreeSurface(sw->screen);
    if (sw->screen_mutex) g_mutex_free(sw->screen_mutex);
    CONDGFREE(sw->pwwlo);
#endif
    if (sw->il) g_free(sw->il);
    g_free(sw);
}

int sw_add_line(struct subwin *sw, gchar *line, int eol){
    int len, a;
    gchar *c, *last, *str, fill[10];
    GString *gs;
      
/*    dbg("add_line '%s' %d \n", line, eol);*/
    len = strlen(line);
/*    if (len>0 && line[len-1]=='\r') line[len-1]='\0';*/
    
    
    if (sw->eol || sw->lines->len==0){
        if (sw->offset > 0 && 
            sw->offset < sw->maxlen-sw->h) {
            sw->offset++;
        }
        g_ptr_array_add(sw->lines, g_strdup(line));
        str = g_ptr_array_index(sw->lines, sw->lines->len - 1);
    }
    else{
        last = g_ptr_array_index(sw->lines, sw->lines->len - 1);
        str = g_strconcat( last, line, NULL);
        g_free(last);
    }

    if (eol) {
        char *d;
        /*dbg("complete line: '%s'\n", str);*/
        dxc_read_spot(str);
        d=g_strconcat("DX ",str,"\n",NULL);
        rel_write_all(d);
        g_free(d);
    }
    
    c = index(str, '\t');
    if (c){
        gs = g_string_new(str);
        c = index(gs->str, '\t');
        while (c){
            a = c - gs->str;
            strcpy(fill, "         ");
            fill[8-(a%8)]='\0';
            g_string_erase(gs, a, 1);
            g_string_insert(gs, a, fill);
            c = index(gs->str, '\t');
        }
        g_free(str);
        str = g_strdup(gs->str);
        g_string_free(gs, 1);
        
    }
    
    g_ptr_array_index(sw->lines, sw->lines->len - 1) = str;
    sw->eol = eol;
    return 0;
}

int sw_add_block(struct subwin *sw, gchar *data){
    gchar *c, *d, *s;

    /*dbg("add_block '%s'\n", data);*/
    c = s = data;
    while (c != NULL && strlen(s)>0){
        c = index(s, '\n');
        if (c) {
            d = g_strndup(s, c-s);
            sw_add_line(sw, d, 1);
            g_free(d);
            s = c+1;
        }else{
            sw_add_line(sw, s, 0);
        }
    }
    sw_check_len(sw);
    redraw_later();
    return 0;
}

int sw_default_func(struct subwin *sw, struct event *ev, int fw){
    /*dbg("sw_default_func %p,[%d,%d,%d,%d],%d)\n",sw,ev->ev,ev->x,ev->y ,ev->b,fw);*/
/*    dbg("              term %dx%d \n",term->x, term->y);*/
    switch(ev->ev){
        case EV_ABORT:
            if (sw->il) 
                inputln_func(sw->il,ev);
            if (sw->pid)
                sw_pipe_kill(sw);
            break;
        case EV_INIT:
            
            
            break;
        case EV_RESIZE:
            sw->w = term->x - 2;
            sw->h = term->y - QSONR_HEIGHT - 4 - cfg->loglines;
            if (aband) sw->h -= aband->spypeers->len;

            sw->hh = sw->h;

            /*dbg("sw_default_func: title=%s term->y=%d sw->h=%d\n", sw->title, term->y, sw->h); */
            
            if (sw->write_fd>=0 && sw->write_fd==sw->read_fd &&
                (sw->ws.ws_col != sw->w ||
                sw->ws.ws_row != sw->h- 1)){

                sw->ws.ws_col = sw->w;
                sw->ws.ws_row = sw->h - 1;
                ioctl(sw->write_fd, TIOCSWINSZ, (char*)&sw->ws);
            }
            
            if (sw->il){
                /*struct inputln *il;
                sw->il->x = sw->x;
                sw->il->y = sw->y + sw->h - 1;
                sw->il->l = sw->w;
                il=sw->il;
                dbg("sw_defa_func RESIZE %p term->y=%d il->x=%d il->y=%d il->band=%p\n", il, term->y, il->x, il->y, il->band);
                draw_inputln(sw->il, 1); */
                sw->h--;
            }   
#ifdef HAVE_SDL            
            if (sw->screen){
                LOCK(sw->screen);
                SDL_FreeSurface(sw->screen);
                sw->screen = SDL_CreateRGBSurface(SDL_SWSURFACE, sw->w*FONT_W, sw->h*FONT_H, sdl->bpp, 
                    sdl->screen->format->Rmask, sdl->screen->format->Gmask, sdl->screen->format->Gmask, 0);
                if (sw->type==SWT_MAP) {
                    map_update_layout(sw);
                    sw->gdirty=1;
                }
                UNLOCK(sw->screen);
            }
#endif
        case EV_REDRAW:
            sw->redraw(sw);
            if (sw->il) {
                inputln_func(sw->il,ev);
            }
            
            break;
        case EV_KBD:
            if (sw->kbd_func(sw, ev, fw)) return 1;
            break;
        case EV_MOUSE:
            if ((ev->b & B_MOVE) ==0){
                if (!gses->focused){
                   sw_set_focus();
                   il_unset_focus(INPUTLN(aband));
                   redraw_later();
                }
            }
            if (sw->mouse_func(sw, ev, fw)) return 1;
            break;
        default:
            error("ERROR: unknown event");    

    }
    return 0;
}


/* for init,abort & resize */
int sw_all_func(struct event *ev, int fw){
    struct subwin *sw;
    int i;

    for (i=0; i<gses->subwins->len; i++){
        sw = g_ptr_array_index( gses->subwins, i);
        sw_default_func(sw, ev, 1);
    }
    return 0;
}

/* returns 1 if event was handled */
int sw_focus_func(struct event *ev, int fw){
    if (gses->focused)
        return sw_ontop_func(ev,fw);
    return 0;
}

int sw_ontop_func(struct event *ev, int fw){
    struct subwin *sw;
    int i;

    for (i=0; i<gses->subwins->len; i++){
        sw = g_ptr_array_index( gses->subwins, i);
        if (sw->ontop){
            return sw_default_func(sw, ev, 1);
        }
    }
    return 0;
}

struct subwin *find_sw_ontop(){
    struct subwin *sw;
    int i;

    for (i=0; i<gses->subwins->len; i++){
        sw = g_ptr_array_index( gses->subwins, i);
        if (sw->ontop) return sw;
    }
    return NULL;
}

void sw_set_focus(){
    struct subwin *sw;

    sw = gses->ontop;
    il_set_focus(sw->il);
    gses->focused = 1;
    if (aband){ 
        gses->ontop->cur = aband->qsos->len;
    }
    gses->ontop->check_bounds(gses->ontop);
}

void sw_unset_focus(){
    il_unset_focus(gses->ontop->il);
    gses->ontop->cur = 0;
    gses->focused = 0;
    if (gses->ontop->type != SWT_STAT)
        gses->ontop->offset = 0; 
}

struct subwin *sw_set_ontop(int n){
    struct subwin *sw,*swret;
    int i;

    swret=NULL;
    if (n<0 || n>=gses->subwins->len) return swret;
    for (i=0; i<gses->subwins->len; i++){
        sw = g_ptr_array_index( gses->subwins, i);
        if (i==n){
            int raise=0;
            
            sw->ontop = 1;
            sw->unread = 0;
            if (gses->ontop != sw) raise=1;
            gses->ontop = sw;
            if (sw->il) il_set_focus(sw->il);
            swret = sw;
            if (sw->raise) sw->raise(sw);
        }else{
            sw->ontop = 0;
        }
        
    }
    return swret;
    
}

struct subwin *sw_totop_next(int n){
    struct subwin *sw,*swret;
    int i;

    swret=NULL;
    for (i=0; i<gses->subwins->len; i++){
        sw = g_ptr_array_index( gses->subwins, i);
        if (sw == gses->ontop) break;
    }
    n+=i;
    if (n<0) n = gses->subwins->len-1;
    if (n>gses->subwins->len-1) n=0;

    return sw_set_ontop(n);
}




void draw_titles(int col_active, int col_passive){
    struct subwin *sw;
    gchar *c;
    int i,x,max;
    
    /*dbg("draw_titles\n");*/
    sw = g_ptr_array_index( gses->subwins, 0);
    if (!sw) return;
    x=sw->x+1;
    

    for (i=0; i<gses->subwins->len; i++){
        sw = g_ptr_array_index( gses->subwins, i);
        if (sw->ontop){
            c=g_strdup_printf("[%i:%s]", i+1, sw->title);
            if (x+strlen(c)>=sw->w+1) max=sw->w-x+1; else max=-1;
            print_text(x,sw->y-1,max,c,col_active);
        }else{    
            c=g_strdup_printf(" %i:%s ", i+1, sw->title);
            if (x+strlen(c)>=sw->w+1) max=sw->w-x+1; else max=-1;
            print_text(x,sw->y-1,max,c,sw->unread?COL_YELLOW:col_passive);
        }
        sw->titl1=x;
        x+=strlen(c)+1;
        sw->titl2=x-2;
        g_free(c);
    }
}

void sw_default_redraw(struct subwin *sw){
    
    draw_frame(sw->x,sw->y,sw->w,sw->h-1,COL_NORM,1);
    draw_frame(sw->x+1,sw->y+1,sw->w-2,sw->h-3,COL_NORM,1);
}


void sw_check_len(struct subwin *sw){
    gpointer p;
    int count,i;
    
    count = sw->lines->len - sw->maxlen;
    if (count>0){
        for (i=0; i<count; i++) {
            p = g_ptr_array_index(sw->lines, 0);   
            /*dbg("scl: %d:%p = '%s'\n",i, p, p); */
            g_free(p);
            g_ptr_array_remove_index(sw->lines, 0);
        }
    }
}

void sw_set_unread(struct fifo *fifo){
    struct subwin *sw;
    int i;

    if (!gses) return;
    for (i=0; i<gses->subwins->len; i++){
        sw = g_ptr_array_index( gses->subwins, i);
/*        dbg(" %p",sw->fifo);*/
        if (sw->type == SWT_LOG) continue; /* don't highlight fifo */
        if (fifo != sw->fifo) continue;
        
        if (!sw->ontop && !sw->unread) {
            sw->unread=1;
            redraw_later();
        }
    }
}

void sw_unset_unread(struct fifo *fifo){
    struct subwin *sw;
    int i;

    if (!gses || !gses->subwins) return;
    for (i=0; i<gses->subwins->len; i++){
        sw = g_ptr_array_index( gses->subwins, i);
/*        dbg(" %p",sw->fifo);*/
        if (sw->type == SWT_LOG) continue; /* don't highlight fifo */
        if (fifo != sw->fifo) continue;
        
        if (sw->unread) {
            sw->unread=0;
            redraw_later();
        }
    }
}


#define sw_highlight(text, ho, needle, color){\
    gchar *cc, *d, *fd; \
    int rx, fx, fl; \
    \
    if ((needle) && strlen(needle)>=2){ \
        cc=(text); \
        while ((d=my_strcasestr((cc), (needle)))!=NULL){ \
            fl=MIN(sw->w-(d-(text))+(ho) , strlen(needle)); \
            fx=rx=d-(text)-(ho); \
            fd=d; \
            if (rx<0) { \
                fl+=rx; \
                fx=0; \
                fd=d-rx; \
            } \
            if (fl>0) print_text(sw->x+fx, sw->y+i, fl, fd, (color)); \
            cc=d+strlen(needle); \
        } \
    }\
}

char *suffix(gchar *call){
    char *needle;
      if (!call) return NULL;
    for (needle=call+strlen(call)-1; 
         needle>=call && isalpha(*needle); 
         needle--); 
    return needle+1;
}
    

struct config_subwin *get_config_sw_by_number(GPtrArray *sws, int nr){
    struct config_subwin *csw;
    int i;

    for (i=0; i<sws->len; i++){
        csw = (struct config_subwin *)g_ptr_array_index(sws, i);
        if (csw->nr==nr) return csw;
    }
    return NULL;   
}


/********************** QSOS ****************************************/

/* only EV_KBD */
int sw_qsos_kbd_func(struct subwin *sw, struct event *ev, int fw){
    /*dbg("sw_qsos_func [%d,%d,%d,%d]\n",ev->ev,ev->x,ev->y,ev->b);*/
    union cba_t cba;

    switch(kbd_action(KM_MAIN,ev)){
        case ACT_ESC:
            return 0;
            break;
        case ACT_DOWN:
            sw->cur++;
            sw_qsos_check_bounds(sw);
            redraw_later();
            return 1;
        case ACT_UP:
            sw->cur--;
            sw_qsos_check_bounds(sw);
            redraw_later();
            return 1;
        case ACT_PAGE_DOWN:
            sw->cur += sw->h - 1;;
            sw_qsos_check_bounds(sw);
            redraw_later();
            return 1;
        case ACT_PAGE_UP:
            sw->cur -= sw->h - 1;;
            sw_qsos_check_bounds(sw);
            redraw_later();
            return 1;
        case ACT_HOME:
            sw->cur = 1;
            sw_qsos_check_bounds(sw);
            redraw_later();
            return 1;
        case ACT_END:
            if (!aband) return 1;
            sw->cur = aband->qsos->len;
            sw_qsos_check_bounds(sw);
            redraw_later();
            return 1;
        case ACT_ENTER:
            if (!aband) return 1;
            sw_qsos_check_bounds(sw);
            if (aband->readonly) {
                errbox(VTEXT(T_BAND_RO), 0);
                return 1;
            }
            if (sw->cur==0) break;
            edit_qso(get_qso(aband, sw->cur-1));
            
            return 1;    
        case ACT_SKED: 
            if (!aband) return 0;
            if (sw->cur==0) break;
            sked_from_qso(get_qso(aband, sw->cur-1));
            return 1;
            case ACT_SCROLL_LEFT:
          if (sw->ho>0) sw->ho--;
            redraw_later();
            return 1;
            case ACT_SCROLL_RIGHT:
                if (sw->ho<73) sw->ho++;
            redraw_later();
            return 1;
        case ACT_CALLINFO:
            if (sw->cur==0) break;
            cba.qso=get_qso(aband, sw->cur-1);
            call_info(cba);
            return 1;

        
    }
    return 0;
}

int sw_qsos_mouse_func(struct subwin *sw, struct event *ev, int fw){
    int y0;
    
    /*dbg("sw_qsos_mouse_func\n");*/
  /*  if ((ev->b & BM_ACT)!=B_DOWN) return 0; */
    switch (ev->b & BM_EBUTT){
        case B_LEFT:
            if (!aband) return 1;
            y0=0;
            if (aband->qsos->len+1 <= sw->h)
                y0 = sw->h - (aband->qsos->len+1) + 1;
            
            sw->cur = aband->qsos->len + 1 - sw->h + ev->y - sw->y - sw->offset + y0;
            sw_qsos_check_bounds(sw);
            redraw_later();
            return 1;
        case B_MIDDLE:
        /*    dbg("middle\n");*/
            break;
        case B_RIGHT:
            /*dbg("right\n");*/
            break;
        case B_WHUP:
            /*dbg("wheel up\n");*/
            sw->cur-=3;
            sw_qsos_check_bounds(sw);
            redraw_later();
            return 1;
        case B_WHDOWN:
            /*dbg("wheel down\n");*/
            sw->cur+=3;
            sw_qsos_check_bounds(sw);
            redraw_later();
            return 1;
    }
    return 0;
}

int show_qs(){ /* gses->qs is locked */
    
    if (aband){
        if (( aband->qs->len>0 || 
              aband->oqs->len>0 || 
              gses->qs->len>0 ) 
            && aband->il->focused ) return 1;
    }else{
        /*if (gses->qs->len>0) return 1;    */
        if (gses->qs->len>0 && INPUTLN(aband)->focused) return 1;
    }
    return 0;
}

void sw_qs_redraw(){ /* gses->qs is locked */
    int i, max0, max1, max2;
    gchar *c;
    struct subwin *sw=NULL;

    for (i=0;i<gses->subwins->len;i++){
        sw=(struct subwin *)g_ptr_array_index(gses->subwins,i);
        if (sw->type!=SWT_QSOS) continue;
        break;
    }
    if (i==gses->subwins->len) return;
    
    max0=26;
    if (term->x-3<max0) max0=term->x-3;
    if (max0<0) max0=0;
    max1=26;
    if (term->x-32<max1) max1=term->x-32;
    if (max1<0) max1=0;
    max2=53;
    if (term->x-62<max2) max2=term->x-62;
    if (max2<0) max2=0;

    for (i=0;i<sw->h;i++){
    
        set_char(28, sw->y+i, 0x8000|COL_NORM|179);
        set_char(58, sw->y+i, 0x8000|COL_NORM|179);
        if (i==sw->h-1) {
            if (ctest)
                print_text(sw->x+ 1+3 ,sw->y+i,-1,VTEXT(T_THIS_BAND),COL_NORM);
            else 
                print_text(sw->x+ 1+3 ,sw->y+i,-1,VTEXT(T_CW_DB),COL_NORM);
            
            if (ctest && ctest->bands->len>1)
                print_text(sw->x+30+3 ,sw->y+i,-1,VTEXT(T_OTHER_BANDS),COL_NORM);
            else
                print_text(sw->x+30+3 ,sw->y+i,-1,VTEXT(T_CW_DB),COL_NORM);
            
            print_text(sw->x+60+3 ,sw->y+i,-1,VTEXT(T_CW_DB),COL_NORM);
            continue;
        }

        if (ctest){
            if (i<aband->qs->len){
                c = g_ptr_array_index(aband->qs, i);
                print_text(sw->x+1 ,sw->y+i,max0,c,COL_NORM);
            }
            if (ctest->bands->len>1){
                if (i<aband->oqs->len){
                    c = g_ptr_array_index(aband->oqs, i);
                    print_text(sw->x+30 ,sw->y+i,max1,c,COL_NORM);
                }
            
                if (i<gses->qs->len){
                    c = g_ptr_array_index(gses->qs, i);
                    print_text(sw->x+60,sw->y+i,max2,c,COL_NORM);
                }
            }else{
                if (i<gses->qs->len){
                    c = g_ptr_array_index(gses->qs, i);
                    print_text(sw->x+30,sw->y+i,max1,c,COL_NORM);
                }

                if (i+sw->h-1 < gses->qs->len){
                    c = g_ptr_array_index(gses->qs, i + sw->h-1 );
                    print_text(sw->x+60,sw->y+i,max2,c,COL_NORM);
                }
            }
        }else{
            if (i<gses->qs->len){
                c = g_ptr_array_index(gses->qs, i);
                print_text(sw->x+1,sw->y+i,max0,c,COL_NORM);
            }

            if (i+sw->h-1 < gses->qs->len){
                c = g_ptr_array_index(gses->qs, i + sw->h-1 );
                print_text(sw->x+30,sw->y+i,max1,c,COL_NORM);
            }

            if (i+2*(sw->h-1) < gses->qs->len){
                c = g_ptr_array_index(gses->qs, i + 2*(sw->h-1) );
                print_text(sw->x+60 ,sw->y+i,max2,c,COL_NORM);
            }
        }
        
    }
}


void sw_qsos_redraw(struct subwin *sw){
    int i,index, y0;
    struct qso *q;
    gchar *c;
    char dtime[6];


    /*dbg("term->x=%d max0=%d max1=%d max2=%d \n", term->x, max0, max1, max2);*/

    LOCK(gses->qs);
    if (show_qs()){
        sw_qs_redraw();
        UNLOCK(gses->qs);
        return;
    }
    UNLOCK(gses->qs);

    if (!aband) return;
        
    y0=0;
    if (aband->qsos->len+1 <= sw->h)
        y0 = sw->h - (aband->qsos->len+1) + 1;
    
    for (i=0;i<sw->h;i++){
        gchar call[50];
        char new[10];
        char qsop[10];
        char suspcall, susploc,unkcall;
        char qtf[10];

        index = aband->qsos->len+1-sw->h + i - sw->offset;
        if (index < 1) {
            print_text(sw->x,sw->y+i-y0+sw->h,-1," ~",COL_NORM);
            continue;
        }

        q = get_qso(aband,index-1);
        strcpy(call,q->callsign);
        if (q->error) {
            if (q->callsign && strcmp(q->callsign, "ERROR")!=0){
                sprintf(call, "ERROR %s", q->callsign);
                lc(call+5);
            }else
                strcpy(call, "ERROR");
        }
        call[12]='\0';
        
        strcpy(new, "");
        if (ctest->wwlused && (q->new&NEW_WWL)) strcat(new,"w");
        if (                   q->new&NEW_DXC ) strcat(new,"d");
        if (ctest->excused && (q->new&NEW_EXC)) strcat(new,"e");
        if (q->qsl)                             strcat(new,"q");
        if (q->remark && strlen(q->remark)>0)   strcat(new,"r");

        if (!q->dupe) sprintf(qsop,"%6d", q->qsop);
        else strcpy(qsop, "DUPE");
            
        dtime[0]=q->time_str[0]; dtime[1]=q->time_str[1]; dtime[2]='.';
        dtime[3]=q->time_str[2]; dtime[4]=q->time_str[3]; dtime[5]='\0';
        
        if (q->suspcall==1) suspcall='?';
        else if (q->suspcall==2) suspcall='!';
        else suspcall=' ';
        if (q->susploc==1) susploc='?';
        else if (q->susploc==2) susploc='!';
        else susploc=' ';
        if (q->unkcall) unkcall=VTEXT(T_HK_NEW_CALL)[0];
        else unkcall=' ';
        sprintf(qtf,"%3d", q->qtf);
#ifdef HAVE_SDL        
        if (sdl) strcat(qtf, "");
#endif
        
        c=g_strdup_printf("  %8s %5s %-12s%c%5s%4s%5s%4s %-4s %-6s %c%c%6s %-4s%-5s %-7s %s",
                q->date_str, dtime, call, suspcall, 
                q->rsts, q->qsonrs, q->rstr, q->qsonrr,
                q->exc, q->locator, susploc, unkcall,
                qsop, *q->locator?qtf:"", new, q->operator,
                q->remark);

        if (index==sw->cur) fill_area(sw->x, sw->y+i-y0, sw->w, 1, COL_INV);
        if (strlen(c)>sw->ho) 
            print_text(sw->x,sw->y+i-y0,sw->w,c+sw->ho, index==sw->cur? COL_INV : COL_NORM);
        
        
        g_free(c);
        
    }
    /*dbg("\n");*/
}

void sw_qsos_check_bounds(struct subwin *sw){

    if (!aband) return;
    
    /*dbg("sw_qsos_check_bounds cur=%d, offset=%d ", sw->cur, sw->offset);*/
    
    if (sw->cur < 1 )   sw->cur = 1;
    if (sw->cur > aband->qsos->len) sw->cur = aband->qsos->len;

    
    if (sw->cur > aband->qsos->len - sw->offset -1 ){
        sw->offset = aband->qsos->len - sw->cur;
    }
    if (sw->cur < aband->qsos->len - sw->h + 1 - sw->offset){
        sw->offset = aband->qsos->len - sw->h - sw->cur + 1;
    }
    if (sw->offset < 0) sw->offset=0;
/*    dbg(" ---> cur=%d, offset=%d\n", sw->cur, sw->offset);*/
}


/************************ FIFO *******************************/

/* only EV_KBD */
int sw_fifo_kbd_func(struct subwin *sw, struct event *ev, int fw){
    /*dbg("sw_fifo_func [%d,%d,%d,%d]\n",ev->ev,ev->x,ev->y,ev->b);*/
    
   /* if (sw->il &&
        sw->il->wasctrlv &&    
            ev->x!='[' &&
            ev->x!=']'){
        dbg("xxx\n");
        if (inputln_func(sw->il, ev)) return 1;
    } */
    if (sw->il && (
        sw->il->wasctrlv ||    
            (ev->x!='[' && ev->x!=']') )){
          if (inputln_func(sw->il, ev)) return 1;
      }

    switch(kbd_action(KM_MAIN,ev)){
        case ACT_ESC:
            return 0;
            break;
        case ACT_DOWN:
            sw->offset--;
            sw->check_bounds(sw);
            redraw_later();
            return 1;
        case ACT_UP:
            sw->offset++;
            sw->check_bounds(sw);
            redraw_later();
            return 1;
        case ACT_PAGE_DOWN:
            sw->offset -= sw->h - 1;;
            sw->check_bounds(sw);
            redraw_later();
            return 1;
        case ACT_PAGE_UP:
            sw->offset += sw->h - 1;;
            sw->check_bounds(sw);
            redraw_later();
            return 1;
        case ACT_HOME:
            sw->offset = fifo_len(sw->fifo) - sw->h; 
            sw->check_bounds(sw);
            redraw_later();
            return 1;
        case ACT_END:
            sw->offset = 0;
            sw->check_bounds(sw);
            redraw_later();
            return 1;
/*          case ACT_SCROLL_LEFT:
                  if (sw->fifo->ho>0) sw->fifo->ho--;
            redraw_later();
            return 1;
            case ACT_SCROLL_RIGHT:
                  sw->fifo->ho++;
            redraw_later();
            return 1;*/
            case ACT_SCROLL_LEFT:
            if (sw->fifo)
                  if (sw->fifo->ho>0) sw->fifo->ho--;
            if (sw->lines)
                  if (sw->ho>0) sw->ho--;
            redraw_later();
            return 1;
            case ACT_SCROLL_RIGHT:
            if (sw->fifo)
                      sw->fifo->ho++;
            if (sw->lines)
                      sw->ho++;
            redraw_later();
    }
    return 0;
}

int sw_fifo_mouse_func(struct subwin *sw, struct event *ev, int fw){
    if ((ev->b & BM_ACT)!=B_DOWN) return 0;
    switch (ev->b & BM_EBUTT){
        case B_LEFT:
            dbg("x il=%p\n",sw->il);
            if (!sw->il) break;
/*            dbg("y=%d sw->y=%d sw->hh=%d sw->h=%d\n", ev->y, sw->y, sw->hh, sw->h);*/
            if (ev->y==sw->y+sw->h)
                inputln_func(sw->il, ev);
            return 1;
        case B_MIDDLE:
            dbg("middle\n");
            break;
        case B_RIGHT:
            dbg("right\n");
            break;
        case B_WHUP:
            dbg("wheel up\n");
            sw->offset+=3;
            sw->check_bounds(sw);
            redraw_later();
            return 1;
        case B_WHDOWN:
            dbg("wheel down\n");
            sw->offset-=3;
            sw->check_bounds(sw);
            redraw_later();
            return 1;
    }
    return 0;
}


void sw_fifo_redraw(struct subwin *sw){
    int i, index;
    gchar *c, *suff;
    
    /*dbg("sw_log_redraw  log->len=%d sw->h=%d sw->offset=%d \n", fifo_len(sw->fifo), sw->h, sw->offset);*/
    
    for (i=0;i<sw->h; i++){
        index = fifo_len(sw->fifo) - sw->offset - sw->h+i;
        if (index<0 || index>=fifo_len(sw->fifo))
           c = "~"; 
        else
           c = fifo_index(sw->fifo, index);

        if (c && strlen(c)>sw->fifo->ho) {
                  print_text(sw->x, sw->y+i, sw->w, c+sw->fifo->ho, COL_NORM);

            if (!aband) continue;
            sw_highlight(c, sw->fifo->ho,  ctest->pcall, COL_YELLOW);
            if (strlen(ctest->pcall)>=3){
                suff=suffix(ctest->pcall);
                sw_highlight(c, sw->fifo->ho, suff, COL_YELLOW);
            }
            
            sw_highlight(c, sw->fifo->ho,  aband->operator, COL_YELLOW);
            if (strlen(aband->operator)>=3){
                suff=suffix(aband->operator);
                sw_highlight(c, sw->fifo->ho, suff, COL_YELLOW);
            }

        }
    }
    
}

void sw_fifo_check_bounds(struct subwin *sw){
    
    /*if (sw->offset < 0) sw->offset=0;*/
    if (sw->offset > fifo_len(sw->fifo) - sw->h) {
        sw->offset = fifo_len(sw->fifo) - sw->h;
    }
    if (sw->offset < 0) sw->offset=0;
}



/********************** PIPE ****************************************/

/* Return:
 * 0 = not highlighted
 * 1 = highlighted, call not worked
 * 2 = highlighted, call worked
 */

int sw_line_is_highlighted(struct subwin *sw, gchar *c){
    int i;

    for (i=0; i<sw->high->len; i++){
        if (!regcmp(c, g_ptr_array_index(sw->high, i))){
            return 1;
        }
    } 
    return sw_pipe_hihglight(sw, c);
}

void sw_pipe_redraw(struct subwin *sw){
    int i, index, col=COL_NORM;
    gchar *c, *to, *call, *suffcall, *operator, *suffoperator;

      if (ctest){
            call=ctest->pcall;
            operator=aband->operator;
      }else{
            call=cfg->pcall;
            operator=cfg->operator;
            if (!operator || !*operator) operator=NULL;
      }

      if (strlen(call)>3){
            suffcall=suffix(call);
      }else{
            suffcall=NULL;
      }

    if (operator && strlen(operator)>3){
            suffoperator=suffix(operator);
      }else{
            suffoperator=NULL;
      }
      to=g_strconcat("to ", call, NULL);
    
/*    dbg("sw_pipe_redraw: offset=%d\n", sw->offset);*/
    for (i=0;i<sw->h; i++){
        index = sw->lines->len - sw->offset - sw->h +i;
        if (index<0 || index>=sw->lines->len)
           c = "~"; 
        else
           c = g_ptr_array_index(sw->lines, index);
        if (c && strlen(c)>sw->ho){
            switch (sw_line_is_highlighted(sw, c)){
                case 0:
                    col=COL_NORM;
                    break;
                case 1:
                    col=COL_YELLOW;
                    break;
                case 2:
                    col=COL_DARKYELLOW;
                    break;
            }
            print_text(sw->x, sw->y+i, sw->w, c + sw->ho, col);

                  sw_highlight(c, sw->ho,  call, COL_RED);
                  if (suffcall){
                        sw_highlight(c, sw->ho, suffcall, COL_RED);
                  }
                  if (operator){
                        sw_highlight(c, sw->ho,  operator, COL_RED);
                        if (suffoperator){
                              sw_highlight(c, sw->ho, suffoperator, COL_RED);
                        }
                  }
            
                  sw_highlight(c, sw->ho, to, COL_RED);

        }
    }
      g_free(to);
}


void sw_pipe_check_bounds(struct subwin *sw){
    
    if (sw->offset < 0) sw->offset=0;
    if (sw->offset > sw->lines->len - 1) {
        sw->offset = sw->lines->len - 1;
    }
    if (sw->offset < 0) sw->offset=0;
}

static time_t lastenter = 0;

void sw_pipe_enter(void *data, gchar *str){
    struct subwin *sw;
    int towrite, written;
    sw = (struct subwin*)data;

    /*dbg("sw_pipe_enter(%p,'%s')\n",data,str);*/
    
    if (sw->write_fd == -1) return;
    
    towrite = strlen(str);
    dbg("towrite = %d\n", towrite);
    if (towrite>100) {
        internal("towrite>100");
    }
    if (time(NULL) == lastenter){
        internal("time() == lastenter");
    }else{
        lastenter = time(NULL);
    }

    written = write(sw->write_fd, str, towrite);
    /*dbg("   towrite=%d  written=%d (%d)\n", towrite, written, errno);*/
    write(sw->write_fd, "\n", 1);
}

#ifdef HAVE_PTY_H
int sw_pty_run(struct subwin *sw, char *cmd){
    int master,i;
      char errbuf[1024];

    sw->pid = forkpty(&master, NULL, NULL, &sw->ws);
    if (sw->pid<0) return -1;
    if (sw->pid==0){ /* child */
        setenv("TERM", "dumb", 1);
        for (i=3;i<1024;i++) close(i);
        /*execlp("/bin/sh", "/bin/sh", "-c", cmd, NULL);*/
        execlp("/bin/sh", "-sh", NULL);
        fprintf(stderr, "*** exec failed errno=%d %s\n", errno, strerror_r(errno, errbuf, sizeof(errbuf)));
        exit(-1);
    }
    else{ /* parent */
        /*dbg("masted_fd is %d\n", master);*/
        sw->write_fd = master; /* sdin of cmd */
        sw->read_fd  = master; /* stdout and stderr of cmd */

        set_handlers(sw->read_fd, sw_pipe_read_handler, NULL,  sw_pipe_exception_handler, (union cba_t)sw);
    }
    return 0;
}
#endif

int sw_pipe_run(struct subwin *sw, char *cmd){
    int pipe1[2], pipe2[2];
    int i;
    
    pipe(pipe1);
    pipe(pipe2);
    
    sw->pid = fork();
    if (sw->pid<0) return -1;
    if (sw->pid==0){ /* child */
        for (i=0; i<20; i++){
            if (i==pipe1[0] || i==pipe2[1]) continue;
            close(i);
        }
        dup(pipe1[0]);
        dup(pipe2[1]);
        dup(pipe2[1]);
        close(pipe1[0]);
        close(pipe2[1]);
        for (i=3;i<1024;i++) close(i);
        execlp("/bin/sh", "/bin/sh", "-c", cmd, NULL);
        exit(-1);
    }
    else{ /* parent */
        close(pipe1[0]);
        close(pipe2[1]);
        sw->write_fd = pipe1[1]; /* sdin of cmd */
        sw->read_fd  = pipe2[0]; /* stdout and stderr of cmd */

        set_handlers(sw->read_fd, sw_pipe_read_handler, NULL,  sw_pipe_exception_handler, (union cba_t)sw);
        set_handlers(sw->write_fd, NULL, NULL,  sw_pipe_exception_handler, (union cba_t)sw);
    }
    return 0;
}

void sw_pipe_read_handler(union cba_t cba){
    struct subwin *sw;
    char buf[1030], *d;
    int ret,i;

    sw = cba.subwin;

    memset(buf, 0, sizeof(buf));
    /*dbg("sw_pipe_read_handler\n");*/
    ret = read(sw->read_fd, buf, 1024);
    /*dbg("read returns %d (%d) buf='%s' \n", ret, errno, buf);*/
    if (ret<=0) {
        sw_add_block(sw, VTEXT(T_PROC_EXITED));
        sw_pipe_kill(sw);
        return;
    }
    for (i=0,d=buf;i<ret;i++){
        if (buf[i]=='\0') continue;
        if (buf[i]=='\r') continue;
        *d=buf[i];
        d++;
    }
    *d='\0';
    buf[ret]='\0';
    sw_add_block(sw, buf);
    if (!sw->ontop && !sw->unread) {
        sw->unread=1;
        redraw_later();
    }

}

void sw_pipe_write_handler(union cba_t cba){
    struct subwin *sw;

    sw = cba.subwin;

    /*dbg("sw_pipe_write_handler\n");*/

}

void sw_pipe_exception_handler(union cba_t cba){
    struct subwin *sw;

    sw = cba.subwin;

    /*dbg("sw_pipe_exception_handler\n");*/
    sw_pipe_kill(sw);
}

void sw_pipe_kill(struct subwin *sw){

    /*dbg("sw_pipe_kill\n");*/
    
    kill(sw->pid, SIGTERM);
    sw->pid = 0;
    
    close(sw->read_fd); 
    set_handlers(sw->read_fd,  NULL, NULL, NULL, CBA0);
    
    if (sw->write_fd != sw->read_fd){
        close(sw->write_fd); 
        set_handlers(sw->write_fd, NULL, NULL, NULL, CBA0);
    }
    sw->read_fd  = -1;
    sw->write_fd = -1;
     
}

#define FREE_SW_CX if (c1) {mem_free(c1); c1=NULL;} if (c2) {mem_free(c2); c2=NULL;}

void sw_toggle_highlight(struct subwin *sw, gchar *s){
    int ret;
    char *c1,*c2;
    char *c, call[25], t[25];
    gchar *key, *value;
    
    /*dbg("sw_toggle_highlight(sw, '%s')\n", s);*/
    c=g_strdup(s);
    uc(c);
    /**** WWC via ON4KST ****/
    /* 1808Z WWC: <f4azf>: jcs done today !! */
    c1=NULL;
    c2=NULL;
    ret=regmatch(c, "^[0-9]{4}Z WWC: <\\**([0-9A-Z\\/]+)\\**>: ", &c1, &c2, NULL);
    if (ret==0){
        safe_strncpy0(call, c2, 19);
        goto doit;
    }
    FREE_SW_CX;
    /**** ON4KST ****/
    /* 1808Z OK1KRQ/P Club> GE all */
    c1=NULL;
    c2=NULL;
    ret=regmatch(c, "^[0-9]{4}Z ([0-9A-Z\\/]+).*>", &c1, &c2, NULL);
    if (ret==0){
        safe_strncpy0(call, c2, 19);
        goto doit;
    }
    FREE_SW_CX;
    /**** WWC ****/
    /* <f4azf>: allok ! */
    c1=NULL;
    c2=NULL;
    ret=regmatch(c, "^<\\**([0-9A-Z\\/]+)\\**>: ", &c1, &c2, NULL);
    if (ret==0){
        safe_strncpy0(call, c2, 19);
        goto doit;
    }
    FREE_SW_CX;
    /**** DX cluster ****/
    /* DX de PA4PS:    144145.0  K6MYC        Tnx eme new# best-20           0841Z */
    c1=NULL;
    c2=NULL;
    ret=regmatch(c, "^DX DE [0-9A-Z]+:..............([0-9A-Z\\/]+)", &c1, &c2, NULL);
    if (ret==0){
        safe_strncpy0(call, c2, 19);
        goto doit;
    }
    FREE_SW_CX;
    /**** DX cluster SH/DX ****/
/* 432160.0  OK1KIR       7-Oct-2007 0010Z  PSE TURN TO JN 76             <S57M>
   2320170.0  OK1KIR       7-Oct-2007 1338Z  tnx qso 678km.                <HA8V>
   24048140.0  OK1KIR       6-Oct-2007 2148Z  jo60pm-jo50vi               <DL6NCI>
   24048100.0  OK1KIR       6-Oct-2007 1314Z  nice 59/59 in JO60LJ         <OK7RA> */
    c1=NULL;
    c2=NULL;
    ret=regmatch(c, "^ *[0-9]+\\.[0-9]  ([0-9A-Z\\/]+) ", &c1, &c2, NULL);
    if (ret==0){
        safe_strncpy0(call, c2, 19);
        goto doit;
    }
    FREE_SW_CX;
    /**** DX cluster login/logout ****/
    /* User OM3TCG has logged in */
    c1=NULL;
    c2=NULL;
    ret=regmatch(c, "^USER ([0-9A-Z\\/]+) HAS LOGGED ", &c1, &c2, NULL);
    if (ret==0){
        safe_strncpy0(call, c2, 19);
        goto doit;
    }
    FREE_SW_CX;
    /**/
doit:;    
   /* dbg("ret=%d  c1='%s'  c2='%s'\n", ret, c1, c2);*/
    FREE_SW_CX;
    g_free(c);
    if (ret) return;

    get_raw_call(t, call);
    

    if (g_hash_table_lookup_extended(gses->hicalls, (gpointer)t, (gpointer)&key, (gpointer)&value)){
        g_hash_table_remove(gses->hicalls, key);
        g_free(key);
        g_free(value);
      dbg("call='%s' removed\n", t);
        
    }else{
        g_hash_table_insert(gses->hicalls, g_strdup(t), g_strdup(""));
      dbg("call='%s' inserted\n", t);
    }
    
/*    dbg("%d\n", g_hash_table_size(gses->hicalls));*/
    redraw_later();
}

int sw_pipe_mouse_func(struct subwin *sw, struct event *ev, int fw){
    int index;
    gchar *c;
    
    if ((ev->b & BM_ACT)!=B_DOWN) return 0;
    switch (ev->b & BM_EBUTT){
        case B_LEFT:
/*            dbg("x il=%p\n",sw->il);*/
            if (!sw->il) break;
/*            dbg("y=%d y=%d hh=%d \n", ev->y, sw->y, sw->hh);*/
            if (ev->y==sw->y+sw->hh){
                inputln_func(sw->il, ev);
                return 1;
            }
            index = sw->lines->len - sw->offset - sw->h + (ev->y - sw->y);
/*            dbg("index=%d\n",index);*/
            if (index<0 || index>=sw->lines->len) break;
            c = g_ptr_array_index(sw->lines, index);
/*            dbg("c='%s'\n", c);*/
            sw_toggle_highlight(sw, c);
            return 1;
        case B_MIDDLE:
/*            dbg("middle\n");*/
            break;
        case B_RIGHT:
/*            dbg("right\n");*/
            break;
        case B_WHUP:
/*            dbg("wheel up\n");*/
            sw->offset+=3;
            sw->check_bounds(sw);
            redraw_later();
            return 1;
        case B_WHDOWN:
/*            dbg("wheel down\n");  */
            sw->offset-=3;
            sw->check_bounds(sw);
            redraw_later();
            return 1;
    }
    return 0;
}

static int sw_match;
void sw_pipe_match(gpointer acall, gpointer nic, gpointer astr){
    gchar *call=acall;
    gchar *str=astr;

    if (sw_match==2) return; /* speed up search, priority when two calls with 1 and 2 are on one line */
    /*dbg("    match call='%s' str='%s'\n", call, str);*/
    if (regcmpi(str, call)!=0) return; 
    sw_match=1;
    
    if (!aband) return;
    if (get_qso_by_callsign(aband, call)==NULL) return;
    sw_match=2;
}

int sw_pipe_hihglight(struct subwin *sw, char *str){
    sw_match=0;
    g_hash_table_foreach(gses->hicalls, sw_pipe_match, str);
  /*  dbg("sw_match: %d\n", sw_match);*/
    return sw_match;
}


/******************** TALK ************************/

void sw_talk_enter(void *enterdata, gchar *str){
    struct subwin *sw;
    gchar *msg, *c, *pband, *operator;
    
    /*dbg("sw_talk_enter(%p,'%s')\n",enterdata,str);*/
    
    sw = (struct subwin *)enterdata;
    
    if (aband){
        pband = g_strdup(aband->pband);
        c = index(pband, ' ');
        if (c) *c='\0';
        operator=aband->operator;
    }else{
        pband="";
        operator=cfg->pcall;
    }
    
    msg=g_strdup_printf("%6s@%-3s: %s", operator, pband, str);
    c=g_strdup_printf("TA %s\n", msg);
    rel_write_all(c);
    g_free(c);
/*    fifo_addf(sw->fifo, "             %s", str);*/
    fifo_addf(sw->fifo,"%6s: %s", operator, str);
    g_free(msg);
}

void sw_talk_read(gchar *data){
    struct subwin *sw;
    int i, unread=0;
   /* dbg("sw_talk_read('%s')\n", data);*/

    for (i=0; i<gses->subwins->len; i++){
        sw = g_ptr_array_index(gses->subwins, i);
        if (sw->type == SWT_TALK){
            fifo_adds(sw->fifo, data);
            log_adds(data);
            /* no sw_check_len ! */
            if (sw->ontop) unread=1;
            if (!sw->ontop) sw->unread=1;
        }
    }
    if (unread) redraw_later();
    return;

}


/**************************** SKED **************************************/

/* 11.52 OK1ZIA@144: 432 MHz .250 OK1MCS in JN69QR (1234km, 359gr) at 12:00 we call (this is a remark ) */
void sw_sked_read(gchar *str, int from_my){
    struct subwin *sw;
    int i, unread=0;
    gchar **items;
    gchar *data1, *data2;
    double qrb,qtf; 
    int qrb_int,qtf_int;

    
    items=g_strsplit(str, ";", 0);
    for (i=0;i<9;i++) {
        if (items[i]==NULL) {
            g_strfreev(items);        
            return;
        }
    }
    
    qrbqtf(ctest->pwwlo, items[8], &qrb, &qtf, NULL, 2);
    qrb_int=(int)qrb;
    qtf_int=(int)(qtf+0.5);
    if (qrb_int < 0.1) {
        qrb_int=0;
        qtf_int=0;
    }  

    data1=g_strdup_printf("%s@%s: %s %s "
                          "%s in %s (%dkm, %ddeg) at "
                          "%s",
            items[1], items[2], items[5], items[3], 
            items[7], items[8], qrb_int,  qtf_int,  
            items[6]);

    data2=g_strdup_printf("            %s.  %s", 
            atoi(items[4])?VTEXT(T_WE_CALL2):VTEXT(T_WE_LISTEN), items[9] );            


    
    for (i=0; i<gses->subwins->len; i++){
        sw = g_ptr_array_index(gses->subwins, i);
        if (sw->type == SWT_SKED){
            fifo_adds(sw->fifo, data1);
            log_adds(data1);
            fifo_adds(sw->fifo, data2);
            
            if (sw->ontop) unread=1;
            if (!sw->ontop) sw->unread=1;
        }
    }
    if (unread) redraw_later();
    
    g_strfreev(items);        
    g_free(data1);
    g_free(data2);
    return;

}

/******************* DX CLUSTER ****************************/

int sw_dxc_kbd_func(struct subwin *sw, struct event *ev, int fw){
    int bi;
    
    if (!aband) return 0;
    bi=lowcase(aband->bandchar)-'a';
    
    switch(kbd_action(KM_MAIN,ev)){
        case ACT_ESC:
            return 0;
            break;
        case ACT_DOWN:
            if (spotdb->cur[bi] && spotdb->cur[bi]->next)
                spotdb->cur[bi] = spotdb->cur[bi]->next;
            redraw_later();
            return 1;
        case ACT_UP:
            if (spotdb->cur[bi] && spotdb->cur[bi]->prev)
                spotdb->cur[bi] = spotdb->cur[bi]->prev;
            redraw_later();
            return 1;
        case ACT_PAGE_DOWN:
            dxc_seek(spotdb, sw->h-1);
            redraw_later();
            return 1;
        case ACT_PAGE_UP:
            dxc_seek(spotdb, -(sw->h-1));
            redraw_later();
            return 1;
        case ACT_HOME:
            spotdb->cur[bi] = spotdb->first[bi];
            redraw_later();
            return 1;
        case ACT_END:
            dxc_seek(spotdb, 0); /* seek to end */
            redraw_later();
            return 1;
            case ACT_SCROLL_LEFT:
            if (sw->ho>0) sw->ho--;
            redraw_later();
            return 1;
            case ACT_SCROLL_RIGHT:
                  sw->ho++;
            redraw_later();
            return 1;
        case ACT_ENTER:
            sw_unset_focus();
            il_set_focus(aband->il);
            if (spotdb->cur[bi]){
                clear_tmpqsos(aband);
                process_input(aband, spotdb->cur[bi]->callsign);
                redraw_later();
            }
            return 1;
        default:
            if (ev->x==' ') {
                if (spotdb->cur[bi]){
                    clear_tmpqsos(aband);
                    process_input(aband, spotdb->cur[bi]->callsign);
                    redraw_later();
                }
            }
    }
    return 0;
}

int sw_dxc_mouse_func(struct subwin *sw, struct event *ev, int fw){
    return 0;
}

void sw_dxc_draw_spot(struct subwin *sw, int i, struct spot *spot,int color){
    gchar *c;
    char callsign[30];

    if (!spot)
        c = g_strdup("~"); 
    else{
        safe_strncpy0(callsign, spot->callsign, 20);
        if (aband && get_qso_by_callsign(aband, spot->callsign)){
            lc(callsign);
        }else{
            uc(callsign);
        }
        c = g_strdup_printf("%04dZ %10.1f %-12s %-8s %s", 
                spot->zulu, spot->qrg, callsign, spot->from, spot->text);
            if (color==COL_NORM && time(NULL) < spot->endbold) color|=0x4000;  
    }
    
    if (c && strlen(c)>sw->ho){
        print_text(sw->x, sw->y+i, sw->w, c + sw->ho, color);
    }
    g_free(c);
}

void sw_dxc_redraw(struct subwin *sw){
    int i,bi;
    struct spot *spot;
    if (!aband) return;
    
    bi=lowcase(aband->bandchar)-'a';
    

    fill_area(sw->x, sw->y+sw->h/2, sw->w, 1, COL_INV);
    sw_dxc_draw_spot(sw, sw->h/2, spotdb->cur[bi], COL_INV);
    
    
    if (spotdb->cur[bi]) spot=spotdb->cur[bi]->prev;
    else                 spot=NULL;

    for (i=sw->h/2-1;i>=0; i--){
        sw_dxc_draw_spot(sw, i, spot, COL_NORM);
        if (spot) spot=spot->prev;
    }
    
    if (spotdb->cur[bi]) spot=spotdb->cur[bi]->next;
    else                 spot=NULL;

    for (i=sw->h/2+1;i<sw->h; i++){
        sw_dxc_draw_spot(sw, i, spot, COL_NORM);
        if (spot) spot=spot->next;
    }
}

void sw_dxc_check_bounds(struct subwin *sw){
    if (!aband) return;
/*    sw->fifo = aband->unfi;
    sw_fifo_check_bounds(sw);*/
}


/******************* UNFINISHED ****************************/

int sw_unfi_kbd_func(struct subwin *sw, struct event *ev, int fw){
    if (!aband) return 0;
    sw->fifo = aband->unfi;
    return sw_fifo_kbd_func(sw, ev, fw);
}

int sw_unfi_mouse_func(struct subwin *sw, struct event *ev, int fw){
    if (!aband) return 0;
    sw->fifo = aband->unfi;
    return sw_fifo_mouse_func(sw, ev, fw);
}

void sw_unfi_redraw(struct subwin *sw){
    if (!aband) return;
    sw->fifo = aband->unfi;
    sw_fifo_redraw(sw);
}

void sw_unfi_check_bounds(struct subwin *sw){
    if (!aband) return;
    sw->fifo = aband->unfi;
    sw_fifo_check_bounds(sw);
}


/******************* STATICTICS ****************************/

int sw_stat_kbd_func(struct subwin *sw, struct event *ev, int fw){
    if (!aband) return 0;
    sw->fifo = aband->statsfifo1;
    return sw_fifo_kbd_func(sw, ev, fw);
}

int sw_stat_mouse_func(struct subwin *sw, struct event *ev, int fw){
    if (!aband) return 0;
    sw->fifo = aband->statsfifo1;
    return sw_fifo_mouse_func(sw, ev, fw);
}

void sw_stat_redraw(struct subwin *sw){
    if (!aband) return;
    sw->fifo = aband->statsfifo1;
    sw_fifo_redraw(sw);
}

void sw_stat_check_bounds(struct subwin *sw){
    if (!aband) return;
    sw->fifo = aband->statsfifo1;
    sw_fifo_check_bounds(sw);
}

void sw_stat_raise(struct subwin *sw){
    /*dbg("sw_stat_raise\n"); */
    if (!aband) return;
    recalc_statsfifo(aband);
}





Generated by  Doxygen 1.6.0   Back to index