static void set_radio_port(gint set_rp)
{
  struct termios settings_radio;
  static struct termios settings_save;
  gchar port_name[13];

  if(fp_radio)
   {
    tcflush(fileno(fp_radio), TCIOFLUSH);
    tcsetattr(fileno(fp_radio), TCSADRAIN, &settings_save);
    fclose(fp_radio);
    fp_radio = NULL;
   }
  if(set_rp)
   {
    if(strcmp(init_screen_choices[18], "<OFF>"))
     {
      strcpy(port_name, "/dev/");
      concat(port_name, init_screen_choices[18],
             1, strlen(init_screen_choices[18])-2, !COPY);

#ifdef BSD
      fp_radio = (fdopen(open(port_name, O_RDWR | O_NONBLOCK), "r+"));
#else
      fp_radio = fopen(port_name, "r+");
#endif

      if(fp_radio)
       { 
        printf("port %s opened\n", port_name);
        radio_model = 0;
        while(strcmp(init_screen_choices[19],
              radio_bracket[radio_model]) && radio_model<NUMBER_OF_RMS)
         radio_model++;
        radio_model--;
        tcgetattr(fileno(fp_radio), &settings_radio);
        settings_save = settings_radio;
        switch (radio_model)
         {
          case RM_FT1000 :
           cfsetispeed(&settings_radio, B4800);
           cfsetospeed(&settings_radio, B4800);
           settings_radio.c_cflag |= CSTOPB;
           break;
          case RM_FT950 :
           cfsetispeed(&settings_radio, B4800);
           cfsetospeed(&settings_radio, B4800);
           settings_radio.c_cflag &= ~CSTOPB;
           break;
          case RM_FT5000 :
           cfsetispeed(&settings_radio, B38400);
           cfsetospeed(&settings_radio, B38400);
           settings_radio.c_cflag &= ~CSTOPB;
           break;
         }

#ifdef BSD
        settings_radio.c_cflag |= CLOCAL;
#endif

        settings_radio.c_lflag &= ~ICANON;
        settings_radio.c_lflag &= ~ECHO;
        settings_radio.c_lflag &= ~ISIG;
        settings_radio.c_oflag &= ~OPOST;
        settings_radio.c_iflag &= ~IXOFF;
        settings_radio.c_iflag &= ~IXON;
        settings_radio.c_cc[VMIN] = 0;
        settings_radio.c_cc[VTIME] = 0;
        tcsetattr(fileno(fp_radio), TCSANOW, &settings_radio);
       }
      else
       printf("cannot open port %s \n", port_name);
     }
   }
}

static void change_radio_frequency(const gchar *new_freq, const gint vfo)
{
  gchar radio_byte[3];
  gint i, idot, hex_byte, lsnf;
  gchar line_out[6] = {0, 0, 0, 0, 0x0a, '\0'};
  gchar line_outy[12];
  const gchar *zero3 = "000";

  if(fp_radio)
   {
    switch (radio_model)
     {
      case RM_FT1000 :
       line_out[4] += vfo*0x80;
       idot = kb_index (new_freq, ".");
       if(idot==4 || idot==5)
        {
         concat(radio_byte, new_freq, idot+1, idot+1, COPY);
         hex_byte = atoi(radio_byte);
         line_out[0] = hex_byte*16;
         idot -= 2;
         i = 1;
         while(idot>-2)
          {
           concat(radio_byte, new_freq, idot>-1 ? idot : idot+1,
                  idot+1, COPY);
           hex_byte = atoi(radio_byte);
           line_out[i] = (hex_byte/10)*16+hex_byte%10;
           idot -= 2;
           i++;
          }
         for(i=0; i<5; i++)
          fputc(line_out[i], fp_radio);
        }
       break;
      case RM_FT950 :
      case RM_FT5000 :
       if(vfo)
        strcpy(line_outy, "FB");
       else
        strcpy(line_outy, "FA");
       lsnf = strlen(new_freq);
       if(lsnf==6)
        strcat(line_outy, "0");
       idot = kb_index (new_freq, ".");
       if(idot==4 || idot==5)
        {
         concat(line_outy, new_freq, 0, idot-1, !COPY);
         concat(line_outy, new_freq, idot+1, lsnf-1, !COPY);
         concat(line_outy, zero3, 0, 3-lsnf+idot, !COPY);
        }
       strcat(line_outy, ";");
       fputs(line_outy, fp_radio);
       if(rcv.kbd_band_change)
        {
         change_radio_rxparams ();
         if(rcv.radio_split==SPLIT_ON)
          {
           change_radio_split (SPLIT_OFF);
           message_box (main_drawing_area, "Split is Off.", REDRAW, CLEAR);
           play_bells (MESSAGE_SOUND);
          }
        }
       break;
      default :
       return;
     }
    fflush(fp_radio);
   }
}

static void change_radio_mode(gint vfo)
{
  gint i;
  gchar vfo_char[2];
  gchar line_out[6] = {0, 0, 0, 0, 0x0c, '\0'};

  if(fp_radio)
   {
    switch (radio_model)
     {
      case RM_FT1000 :
       if(mode==CW || tuning_up)
        line_out[3] = 3;
       else
        line_out[3] = iband/3;
       line_out[3] += vfo*0x80;
       for(i=0; i<5; i++)
        fputc(line_out[i], fp_radio);
       break;
      case RM_FT950 :
       if(vfo==VFOB)
        {
         strcpy(line_out, "SV;");
         fputs(line_out, fp_radio);
        }
       strcpy(line_out, "MD0");
       if(mode==CW || tuning_up)
        strcat(line_out, "3;");
       else if(iband/3)
        strcat(line_out, "2;");
       else
        strcat(line_out, "1;");
       fputs(line_out, fp_radio);
       if(vfo==VFOB)
        {
         strcpy(line_out, "SV;");
         fputs(line_out, fp_radio);
        }
       break;
      case RM_FT5000 :
       int_to_char (vfo, vfo_char);
       strcpy(line_out, "MD");
       strcat(line_out, vfo_char);
       if(mode==CW || tuning_up)
        strcat(line_out, "3;");
       else if(iband/3)
        strcat(line_out, "2;");
       else
        strcat(line_out, "1;");
       fputs(line_out, fp_radio);
       break;
      default :
       return;
     }
    if(!rcv.kbd_band_change)
     change_radio_rxparams ();
    fflush(fp_radio);
   }
}

static gint process_frequency_command(const gchar *new_freq)
{
  gint i;
  gdouble freq;
  gchar freq_char[14];
  gint i1=0, i2=6, ipfc=FALSE;

  freq = convert_frequency (new_freq);
  if(freq<0.)
   return ipfc;
  if(isel_contest==A160)
   i2 = 1;
  else if(isel_contest==TEN)
   i1 = 5;
  for(i=i1; i<i2; i++)
   {
    if(freq>=packet_band_limits[i][0] && freq<=packet_band_limits[i][1])
     {
      ipfc = TRUE;
      if(i!=iband)
       {
        iband = i;
        cr_array[icall_count+1].iband = iband;
        rcv.kbd_band_change = TRUE;
        play_bells (BAND_CHANGE_SOUND);
        if(!icall_count)
         {
          strcpy(init_screen_choices[14], bandw_bracket[iband]);
          write_ini_file ();
         }
       }
      if(mode==PH)
       change_radio_mode (VFOA);
      real_to_char (freq+.001, freq_char, 1);
      change_radio_frequency (freq_char, VFOA);
      break;
     }
   }
  return ipfc;
}

static gdouble convert_frequency(const gchar *new_freq)
{
  gint i, lcall;
  gchar freq_char[14];
  gint isa=0, isd=0;
  gdouble freq=-1.0;

  strcpy(freq_char, new_freq);
  left_blank_unpad (freq_char);
  right_blank_unpad (freq_char);
  lcall = strlen(freq_char);
  for(i=0; i<lcall; i++)
   {
    if(isdigit(freq_char[i]))
     isd++;
    else if(freq_char[i]=='.')
     isa++;
    else if(freq_char[i]=='R')
     {
      freq_char[i] = '.';
      isa++;
     }
    else
     return freq;
   }
  if(!lcall || isa>1 || (isa+isd)!=lcall)
   return freq;
  freq = atof(freq_char);
  if(freq<1000.0)
   {
    freq += packet_band_limits[iband][0];
    if(freq>packet_band_limits[iband][1])
     freq -= fmod(packet_band_limits[iband][0], 1000.0);
   }
  return freq;
}

static void read_radio_port(gint iadd)
{
  ESVars rc_esd;
  gint i, iread, fd;
  gchar bad_freq_char[10], msg[41];
  guchar radio_line[RADIO_LENGTH], radio_line_hold[RADIO_LENGTH];
  gchar radio_liney[RADIO_LENGTHY], radio_liney_hold[RADIO_LENGTHY];
  gint nbytes=0, ihold=-1;
  gchar line_out[6] = {0, 0, 0, 2, 0x10, '\0'};
  static gint bad_freq = FALSE;

  if(fp_radio && !ialt_box && rcv.ready)
   {
    switch (radio_model)
     {
      case RM_FT1000 :
       fd = fileno(fp_radio);
       if(iadd==1)
        {
         iread = read(fd, radio_line_hold, RADIO_LENGTH-1);
         while(iread>0)
          iread = read(fd, radio_line_hold, RADIO_LENGTH-1);
         for(i=0; i<5; i++)
          fputc(line_out[i], fp_radio);
         fflush(fp_radio);
        }
       else if(iadd==2)
        {
         for(i=0; i<RADIO_LENGTH; i++)
          radio_line[i] = 0;
         iread = read(fd, radio_line_hold, RADIO_LENGTH-1-nbytes);
         while(iread>0)
          {
           for(i=0; i<iread; i++)
            radio_line[i+nbytes] = radio_line_hold[i];
           nbytes += iread;
           iread = read(fd, radio_line_hold, RADIO_LENGTH-1-nbytes);
          }
         radio_line[RADIO_LENGTH-1] = '\0';
         if(nbytes==16)
          rcv.radio_freq = 65536*radio_line[1]+256*radio_line[2]+radio_line[3];
         else
          rcv.radio_freq = 0.;
         rcv.radio_freq /= 100.0;
         rcv.radio_freq += 0.002;
         if(rcv.radio_freq<1.)
          return;
        }
       break;
      case RM_FT950 :
      case RM_FT5000 :
       if(iadd==1)
        {
         while(fgets(radio_liney, RADIO_LENGTHY, fp_radio));
         strcpy(radio_liney, "IF;");
         fputs(radio_liney, fp_radio);
         fflush(fp_radio);
        }
       else if(iadd==2)
        {
         fgets(radio_liney, RADIO_LENGTHY, fp_radio);
         if(strlen(radio_liney)==RADIO_LENGTHY-1)
          {
           concat(radio_liney_hold, radio_liney, 5, 12, COPY);
           rcv.radio_freq = atof(radio_liney_hold);
           if((mode==CW && radio_liney[20]!='3') ||
             (mode==PH && radio_liney[20]=='3'))
            {
             change_radio_mode (VFOA);
             if(rcv.radio_split==SPLIT_ON)
              change_radio_mode (VFOB);
            }
          }
         else
          rcv.radio_freq = 0.;
         rcv.radio_freq /= 1000.0;
         rcv.radio_freq += 0.002;
         if(rcv.radio_freq<1.)
          return;
        }
       break;
      default :
       return;
     }
    if(iadd==2)
     {
      if(rcv.kbd_band_change)
       rcv.kbd_band_change = FALSE;
      else
       {
        for(i=0; i<6; i++)
         if(rcv.radio_freq>=packet_band_limits[i][0] &&
            rcv.radio_freq<=packet_band_limits[i][1])
          {
           ihold = i;
           bad_freq = FALSE;
           break;
          }
        if(ihold>-1)
         {
          if(ihold!=iband)
           {
            iband = ihold;
            cr_array[icall_count+1].iband = iband;
            process_ctrld_command (main_drawing_area, &rc_esd);
            update_display (main_drawing_area, REDRAW);
            play_bells (BAND_CHANGE_SOUND);
            if(!icall_count)
             {
              strcpy(init_screen_choices[14], bandw_bracket[iband]);
              write_ini_file ();
             }
            if(rcv.radio_split==SPLIT_ON)
             {
              change_radio_split (SPLIT_OFF);
              message_box (main_drawing_area, "Split is Off.", REDRAW, CLEAR);
              play_bells (MESSAGE_SOUND);
             }
           }
          if(idisplay_type==IDT_PACKET && ipage_screen[0][idisplay_type] &&
             !ireset_display && !mcv.button)
           packet_box (main_drawing_area, !REDRAW, TRUE);
         }
        else
         {
          if(!bad_freq)
           {
            real_to_char (rcv.radio_freq, bad_freq_char, 2);
            strcpy(msg, "Bad Frequency! (");
            strcat(msg, bad_freq_char);
            strcat(msg, ")");
            boxed_message (msg, 2000, LT_GRAY);
            play_bells (BAD_KEY_SOUND);
           }
          bad_freq = TRUE;
         }
       }
     }
   }
}

static void change_radio_split(gint split)
{
  gint i;
  gchar line_out[6] = {0, 0, 0, 0, 0x01, '\0'};

  if(fp_radio)
   {
    switch (radio_model)
     {
      case RM_FT1000 :
       line_out[3] = split;
       for(i=0; i<5; i++)
        fputc(line_out[i], fp_radio);
       break;
      case RM_FT950 :
      case RM_FT5000 :
       if(split)
        strcpy(line_out, "FT3;");
       else
        {
         strcpy(line_out, "AB;");
         fputs(line_out, fp_radio);
         strcpy(line_out, "FT2;");
        }
       fputs(line_out, fp_radio);
       break;
      default :
       return;
     }
    fflush(fp_radio);
    rcv.radio_split = split;
   }
}

static void split_freq_box(void)
{
  GdkRectangle update_rect;
  static SFBVars sfbd = {
   .field_length = 5, .col1 = 57, .cursor_col = 0};
  gint row1=4, col1=16, row2=6, col2=62;
  gint idraw=TRUE;
  const gchar *title = "Set VFO-B Split Frequency";
  const gchar *subtitle = "Set Split/Unsplit:Enter    Exit:Esc";

  update_rect.x = col1*wcol;
  update_rect.y = row1*hrow;
  update_rect.width = (col2-col1-1)*wcol;
  update_rect.height = (row2-row1-1)*hrow;
  ireset_display = FALSE;
  update_display (main_drawing_area, REDRAW);
  main_cursor_type = CURSOR_OFF;
  ialt_box = 'M';
  sfbd.row1 = row1+1;
  sfbd.cursor_col = sfbd.col1;
  sfbd.done = FALSE;
  strcpy(sfbd.field_line, "");
  g_signal_handler_block (main_window, main_key_handler_id);
  sfbd.key_handler_id = g_signal_connect (G_OBJECT (main_window),
                        "key_press_event",
                        G_CALLBACK (sfb_key_handler), &sfbd);
  g_timeout_add (250, sfb_cursor, &sfbd);
  draw_box (row1, col1, row2, col2, 1, LT_GRAY, ORANGE,
            title, WHITE, subtitle, LT_GRAY, SAVEPIX);
  draw_shadow (main_drawing_area, row1, col1, row2, col2, SAVEPIX);
  draw_rectangle (&update_rect, ORANGE, SAVEPIX);
  black_bar (main_drawing_area, row1+1, col1+41, row1+1, col2-1);
  write_line (row1, col1+1,
        "Enter kHz Part Only. Blank to Unsplit.", YELLOW, SAVEPIX);
  gtk_widget_queue_draw_area (main_drawing_area,
                              update_rect.x-idraw*wcol,
                              update_rect.y-idraw*hrow,
                              update_rect.width+idraw*2*wcol,
                              update_rect.height+idraw*2*hrow);
  gtk_main ();
}

static gint sfb_key_handler(GtkWidget *widget, GdkEventKey *event,
                            gpointer data)
{
  SFBVars *sfbd;
  ESVars esd;
  guint ikey;
  gdouble freq, lower_band_limit;
  gchar freq_char[14];
  
  sfbd = (SFBVars*)data;
  ikey = event->keyval;
  ikey = toupper_ui(ikey);
  esd.ikey = ikey;
  esd.cursor_row = sfbd->row1;
  esd.cursor_colp = &sfbd->cursor_col;
  esd.field_col = sfbd->col1;
  esd.field_length = sfbd->field_length;
  esd.field_linep = sfbd->field_line;
  switch (ikey)
   {
    case 65505 : /*left shift*/
    case 65506 : /*right shift*/
    case 65509 : /*caps lock*/
    case 65407 : /*num lock*/
     break;
    case 65361 : /*left_arrow*/
    case 65363 : /*right_arrow*/
    case 65360 : /*home*/
    case 65367 : /*end*/
    case 65535 : /*delete*/
    case 65288 : /*backspace*/
     edit_line (&esd);
     break;
    case 65293 : /*enter*/
     if(strlen(sfbd->field_line))
      {
       freq = convert_frequency (sfbd->field_line);
       if(mode==CW)
        lower_band_limit = packet_band_limits[iband][0];
       else
        lower_band_limit = phone_band_limits[iband];
       if(freq<lower_band_limit || freq>packet_band_limits[iband][1])
        {
         message_box (main_drawing_area, "Frequency Out of Band!",
                      REDRAW, CLEAR);
         play_bells (MESSAGE_SOUND);
         break;
        }
       else
        {
         change_radio_split (SPLIT_ON);
         change_radio_mode (VFOB);
         real_to_char (freq+.001, freq_char, 1);
         change_radio_frequency (freq_char, VFOB);
         message_box (main_drawing_area, "Split is On.", REDRAW, CLEAR);
        }
      }
     else
      {
       change_radio_split (SPLIT_OFF);
       message_box (main_drawing_area, "Split is Off.", REDRAW, CLEAR);
       play_bells (MESSAGE_SOUND);
      }
     sfbd->done = TRUE;
     ialt_box = FALSE;
     main_cursor_type = LINE_CURSOR;
     break;
    case 65307 : /*escape*/
     sfbd->done = TRUE;
     ialt_box = FALSE;
     main_cursor_type = LINE_CURSOR;
     break;
    default :
     if(isdigit_ui(ikey) || ikey=='R')
      edit_line (&esd);
     else
      play_bells (BAD_KEY_SOUND);
   }
  return TRUE;
}

static gint sfb_cursor(gpointer data)
{
  SFBVars *sfbd;
  gint cursor_fg_color, cursor_bg_color;
  static gint iadd = 0;

  sfbd = (SFBVars*)data;
  if(sfbd->done)
   {
    g_signal_handler_disconnect (main_window, sfbd->key_handler_id);
    g_signal_handler_unblock (main_window, main_key_handler_id);
    gtk_main_quit ();
    update_display (main_drawing_area, REDRAW);
    return FALSE;
   }
  iadd++;
  iadd %= 4;
  if(insert_mode)
   {
    cursor_fg_color = BLACK;
    cursor_bg_color = YELLOW;
   }
  else
   {
    cursor_fg_color = YELLOW;
    cursor_bg_color = BLACK;
   }
  cursor_control (main_drawing_area, iadd, 1,
                  sfbd->row1, sfbd->cursor_col,
                  cursor_fg_color, cursor_bg_color);
  return TRUE;
}

static void radio_split_ind(gpointer widget, gint iadd)
{
  gint split_color;

  if(rcv.radio_split)
   {
    if(iadd%2)
     split_color = YELLOW;
    else
     split_color = LT_GRAY;
    write_line (2, 73, "/", split_color, SAVEPIX);
    gtk_widget_queue_draw_area (widget, 73*wcol, 2*hrow, wcol, hrow);
   }
}
static void change_radio_rxparams(void)
{
  gint mb;
  gint ip=0;

  if(fp_radio && strcmp(set_screen_choices[12], cat_bracket[0]))
   {
    mb = 6*mode+iband;
    switch (radio_model)
     {
      case RM_FT1000 :
       return;
       break;
      case RM_FT950 :
      case RM_FT5000 :
       if(strcmp(set_screen_choices[12], cat_bracket[1]))
        ip = 1;
       fputs(rcs[ip].co_onoff[mb], fp_radio);
       fputs(rcs[ip].co_value[mb], fp_radio);
       fputs(rcs[ip].na[mb], fp_radio);
       fputs(rcs[ip].sh[mb], fp_radio);
       fputs(rcs[ip].is[mb], fp_radio);
       fputs(rcs[ip].rf[mb], fp_radio);
       fputs(rcs[ip].gt[mb], fp_radio);
       fputs(rcs[ip].ra[mb], fp_radio);
       fputs(rcs[ip].pa[mb], fp_radio);
       break;
      default :
       return;
     }
    fflush(fp_radio);
   }
}

static void get_cat_filename(gchar *filnam)
{
  gint i, idash;

  for(i=2; i<=NUMBER_OF_RMS; i++)
   if(!strcmp(init_screen_choices[19], radio_bracket[i]))
    {
     idash = kb_index (radio_bracket[i], "-");
     if(idash>-1)
      {
       concat(filnam, radio_bracket[i], 1, idash-1, COPY);
       concat(filnam, radio_bracket[i], idash+1,
              strlen(radio_bracket[i])-2, !COPY);
      }
     else
      concat(filnam, radio_bracket[i], 1, strlen(radio_bracket[i]-2), COPY);
     strcat(filnam, ".CAT");
     break;
    }
}
