static void draw_box(gint irt, gint jcl, gint irb, gint jcr,
                     gint num_lines, gint line_color, gint box_color,
                     const gchar *title, gint title_color,
                     const gchar *subtitle, gint subtitle_color,
                     gint isave_pix)
{
  GdkDrawable *pixwin;
  gint pixs, title_length, subtitle_length;

  if(isave_pix)
   pixwin = pixmap;
  else
   pixwin = main_drawing_area->window;
  pixs = 2*(num_lines/2);
  title_length = strlen(title);
  subtitle_length = strlen(subtitle);
  new_pen (box_color);
  gdk_draw_rectangle (pixwin,
		      gc,
		      TRUE,
		      (jcl-1)*wcol,
                      irt*hrow,
		      wcol,
		      (irb-irt-1)*hrow);
  gdk_draw_rectangle (pixwin,
		      gc,
		      TRUE,
		      (jcl-1)*wcol,
                      (irt-1)*hrow,
		      (jcr-jcl+1)*wcol,
		      hrow);
  gdk_draw_rectangle (pixwin,
		      gc,
		      TRUE,
		      (jcr-1)*wcol,
                      irt*hrow,
		      wcol,
		      (irb-irt-1)*hrow);
  gdk_draw_rectangle (pixwin,
		      gc,
		      TRUE,
		      (jcl-1)*wcol,
                      (irb-1)*hrow,
		      (jcr-jcl+1)*wcol,
		      hrow);
  new_pen (line_color);
  gdk_draw_line (pixwin,
                 gc,
                 (jcl-1)*wcol+wcol/2-pixs,
                 (irt-1)*hrow+hrow/2-pixs,
                 (jcr-1)*wcol+wcol/2+pixs,
                 (irt-1)*hrow+hrow/2-pixs);
  gdk_draw_line (pixwin,
                 gc,
                 (jcl-1)*wcol+wcol/2-pixs,
                 (irb-1)*hrow+hrow/2+pixs,
                 (jcr-1)*wcol+wcol/2+pixs,
                 (irb-1)*hrow+hrow/2+pixs);
  gdk_draw_line (pixwin,
                 gc,
                 (jcl-1)*wcol+wcol/2-pixs,
                 (irt-1)*hrow+hrow/2-pixs,
                 (jcl-1)*wcol+wcol/2-pixs,
                 (irb-1)*hrow+hrow/2+pixs);
  gdk_draw_line (pixwin,
                 gc,
                 (jcr-1)*wcol+wcol/2+pixs,
                 (irt-1)*hrow+hrow/2-pixs,
                 (jcr-1)*wcol+wcol/2+pixs,
                 (irb-1)*hrow+hrow/2+pixs);
  if(num_lines==2)
   {
  gdk_draw_line (pixwin,
                 gc,
                 (jcl-1)*wcol+wcol/2+pixs,
                 (irt-1)*hrow+hrow/2+pixs,
                 (jcr-1)*wcol+wcol/2-pixs,
                 (irt-1)*hrow+hrow/2+pixs);
  gdk_draw_line (pixwin,
                 gc,
                 (jcl-1)*wcol+wcol/2+pixs,
                 (irb-1)*hrow+hrow/2-pixs,
                 (jcr-1)*wcol+wcol/2-pixs,
                 (irb-1)*hrow+hrow/2-pixs);
  gdk_draw_line (pixwin,
                 gc,
                 (jcl-1)*wcol+wcol/2+pixs,
                 (irt-1)*hrow+hrow/2+pixs,
                 (jcl-1)*wcol+wcol/2+pixs,
                 (irb-1)*hrow+hrow/2-pixs);
  gdk_draw_line (pixwin,
                 gc,
                 (jcr-1)*wcol+wcol/2-pixs,
                 (irt-1)*hrow+hrow/2+pixs,
                 (jcr-1)*wcol+wcol/2-pixs,
                 (irb-1)*hrow+hrow/2-pixs);
   }
  if(title_length>0)
   {
    new_pen (box_color);
    gdk_draw_rectangle (pixwin,
                        gc,
                        TRUE,
                        ((jcr-jcl-title_length-2)/2+jcl)*wcol,
                        (irt-1)*hrow,
                        (title_length+2)*wcol,
                        hrow);
    write_line (irt-1, (jcr-jcl-title_length)/2+jcl,
                title, title_color, isave_pix);
   }
  if(subtitle_length>0)
   {
    new_pen (box_color);
    gdk_draw_rectangle (pixwin,
                        gc,
                        TRUE,
                        ((jcr-jcl-subtitle_length-2)/2+jcl)*wcol,
                        (irb-1)*hrow,
                        (subtitle_length+2)*wcol,
                        hrow);
    write_line (irb-1, (jcr-jcl-subtitle_length)/2+jcl,
                subtitle, subtitle_color, isave_pix);
   }
}

static void draw_shadow(GtkWidget *widget, gint row1, gint col1,
                        gint row2, gint col2, gint isave_pix)
{
  GdkRectangle update_rect;
  
  update_rect.x = col2*wcol;
  update_rect.y = row1*hrow;
  update_rect.width = 2*wcol;
  update_rect.height = (row2-row1)*hrow;
  draw_rectangle (&update_rect, BLACK, isave_pix);
  if(isave_pix)
   gtk_widget_queue_draw_area (widget,
                               update_rect.x,
                               update_rect.y,
                               update_rect.width,
                               update_rect.height);
  update_rect.x = (col1+1)*wcol;
  update_rect.y = row2*hrow;
  update_rect.width = (col2-col1+1)*wcol;
  update_rect.height = hrow;
  draw_rectangle (&update_rect, BLACK, isave_pix);
  if(isave_pix)
   gtk_widget_queue_draw_area (widget,
                               update_rect.x,
                               update_rect.y,
                               update_rect.width,
                               update_rect.height);
}

static void draw_updn_arrows(gint irow, gint jcol, gint arrow_color)
{
  GdkGCValues values;
  gint saved_line_width;

  gdk_gc_get_values (gc, &values);
  saved_line_width = values.line_width;
  values.line_width = 1;
  gdk_gc_set_line_attributes (gc,
                              values.line_width,
                              values.line_style,
                              values.cap_style,
                              values.join_style);
  new_pen (arrow_color);
  gdk_draw_line (pixmap,
                 gc,
                 jcol*wcol+wcol/2,
                 (irow-1)*hrow+4,
                 jcol*wcol+wcol/2,
                 irow*hrow-5);
  gdk_draw_line (pixmap,
                 gc,
                 jcol*wcol+wcol/2,
                 (irow-1)*hrow+4,
                 jcol*wcol+1,
                 (irow-1)*hrow+8);
  gdk_draw_line (pixmap,
                 gc,
                 jcol*wcol+wcol/2,
                 (irow-1)*hrow+4,
                 (jcol+1)*wcol,
                 (irow-1)*hrow+9);
  gdk_draw_line (pixmap,
                 gc,
                 (jcol+1)*wcol+wcol/2,
                 (irow-1)*hrow+4,
                 (jcol+1)*wcol+wcol/2,
                 irow*hrow-5);
  gdk_draw_line (pixmap,
                 gc,
                 (jcol+1)*wcol+wcol/2,
                 irow*hrow-5,
                 (jcol+1)*wcol+1,
                 irow*hrow-10);
  gdk_draw_line (pixmap,
                 gc,
                 (jcol+1)*wcol+wcol/2,
                 irow*hrow-5,
                 (jcol+2)*wcol,
                 irow*hrow-11);
  values.line_width = saved_line_width;
  gdk_gc_set_line_attributes (gc,
                              values.line_width,
                              values.line_style,
                              values.cap_style,
                              values.join_style);
}

static void write_line(gint row, gint col, const gchar *line_out,
                       gint lo_color, gint isave_pix)
{
  GdkDrawable *pixwin;

  if(isave_pix)
   pixwin = pixmap;
  else
   pixwin = main_drawing_area->window;
  new_pen (lo_color);
  pango_layout_set_text (layout, line_out, strlen(line_out));
  gdk_draw_layout (pixwin, gc, col*wcol, row*hrow, layout);
}

static void write_markup_line(gint row, gint col, const gchar *line_out,
                              gint lo_color, gint isave_pix)
{
  GdkDrawable *pixwin;
  PangoAttrList *pal;
  gint iup;

  if(isave_pix)
   pixwin = pixmap;
  else
   pixwin = main_drawing_area->window;
  if(kb_index(line_out, "</span>")>-1)
   iup = 66/hrow;
  else
   iup = 0;
  pal = pango_layout_get_attributes (layout);
  new_pen (lo_color);
  pango_layout_set_markup (layout, line_out, -1);
  gdk_draw_layout (pixwin, gc, col*wcol, row*hrow-iup, layout);
  pango_layout_set_attributes (layout, pal);
}

static void draw_rectangle(GdkRectangle *ur_ptr, gint ur_color,
                           gint isave_pix)
{
  GdkDrawable *pixwin;

  if(isave_pix)
   pixwin = pixmap;
  else
   pixwin = main_drawing_area->window;
  new_pen (ur_color);
  gdk_draw_rectangle (pixwin, gc, TRUE, ur_ptr->x, ur_ptr->y,
                      ur_ptr->width, ur_ptr->height);
}

static guint boxed_message(const gchar *bmsg, guint bmsg_time,
                           gint box_color)
{
  static GdkRectangle update_rect;
  static BMVars bmd = {.col1=40, .col2=42};
  gint lbmsg, col1, row2, col2;
  gint row1=12;

  ialt_box = 'B';
  if(idisplay_type==IDT_INFO6 && log_lines[idisplay_type]<14)
   row1 = 26-log_lines[idisplay_type];
  row2 = row1+2;
  lbmsg = strlen(bmsg);
  if(!bmsg_time) lbmsg+=2;
  col1 = 38-lbmsg/2;
  col2 = col1+lbmsg+3;
  gdk_window_process_updates (main_window->window, TRUE);
  update_rect.x = col1*wcol;
  update_rect.y = row1*hrow;
  update_rect.width = (col2-col1-1)*wcol;
  update_rect.height = (row2-row1-1)*hrow;
  draw_box (row1, col1, row2, col2, 1, BLACK, box_color,
            "", BLACK, "", DK_GRAY, !SAVEPIX);
  draw_rectangle (&update_rect, box_color, !SAVEPIX);
  draw_shadow (main_drawing_area, row1, col1, row2, col2, !SAVEPIX);
  write_line (row1, col1+1, bmsg, BLACK, !SAVEPIX);
  if(col1>bmd.col1)
   {
    update_rect.x = bmd.col1*wcol;
    update_rect.width = (bmd.col2-bmd.col1-1)*wcol;
   }
  bmd.row1 = row1;
  bmd.col1 = col1;
  bmd.row2 = row2;
  bmd.col2 = col2;
  bmd.box_color = box_color;
  bmd.answer = 0;
  bmd.done = FALSE;
  if(bmsg_time)
   g_timeout_add (bmsg_time, boxed_unmessage, &update_rect);
  else
   {
    ialt_box = 'A';
    main_cursor_type = CURSOR_OFF;
    if(ialt_de=='E')
     g_signal_handler_block (main_window, pec_key_handler_id);
    else if(idisplay_type==IDT_SET)
     g_signal_handler_block (main_window, set_key_handler_id);
    else
     g_signal_handler_block (main_window, main_key_handler_id);
    bmd.key_handler_id = g_signal_connect (G_OBJECT (main_window),
                         "key_press_event",
                         G_CALLBACK (bm_key_handler), &bmd);
    g_timeout_add (250, bm_cursor, &bmd);
    gtk_main ();
    g_signal_handler_disconnect (main_window, bmd.key_handler_id);
    if(ialt_de=='E')
     g_signal_handler_unblock (main_window, pec_key_handler_id);
    else if(idisplay_type==IDT_SET)
     g_signal_handler_unblock (main_window, set_key_handler_id);
    else
     g_signal_handler_unblock (main_window, main_key_handler_id);
    main_cursor_type = LINE_CURSOR;
    ialt_box = 'B';
    boxed_unmessage (&update_rect);
   }
  return bmd.answer;
}

static gint bm_key_handler(GtkWidget *widget, GdkEventKey *event,
                           BMVars *bmd)
{
  guint ikey;
  
  if(!bmd->done)
   {
    ikey = event->keyval;
    switch (ikey)
     {
      case 'y' :
      case 'Y' :
      case 'n' :
      case 'N' :
       bmd->answer = ikey;
       bmd->done = TRUE;
       break;
      case 65505 : /*left shift*/
      case 65506 : /*right shift*/
       break;
      default :
       play_bells (BAD_KEY_SOUND);
     }
   }
  else
   play_bells (BAD_KEY_SOUND);
  return TRUE;
}

static gint bm_cursor(gpointer data)
{
  BMVars *bmd;
  static gint iadd = 0;

  bmd = (BMVars*)data;
  if(bmd->done)
   {
    gtk_main_quit ();
    return FALSE;
   }
  iadd++;
  iadd %= 4;
  cursor_control (main_drawing_area, iadd, LINE_CURSOR, bmd->row1+1,
                  bmd->col2-2, BLACK, bmd->box_color);
  return TRUE;
}

static gint boxed_unmessage(gpointer data)
{
  GdkRectangle *update_rect;

  if(ialt_box=='B')
   {
    update_rect = (GdkRectangle*)data;
    gtk_widget_queue_draw_area (main_drawing_area,
                                update_rect->x-wcol,
                                update_rect->y-hrow,
                                update_rect->width+4*wcol,
                                update_rect->height+3*hrow);
    ialt_box = FALSE;
   }
  return FALSE;
}

static void rw_error_box(GtkWidget *widget, const gchar *emsg)
{
  GdkRectangle update_rect;
  gint lemsg, col1, col2;
  gint row1=12, row2=14;

  lemsg = strlen(emsg);
  col1 = 38-lemsg/2;
  col2 = col1+lemsg+3;
  update_rect.x = col1*wcol;
  update_rect.y = row1*hrow;
  update_rect.width = (col2-col1-1)*wcol;
  update_rect.height = (row2-row1-1)*hrow;
  draw_box (row1, col1, row2, col2, 1, WHITE, HI_RED,
            "", WHITE, "", LT_GRAY, !SAVEPIX);
  draw_rectangle (&update_rect, HI_RED, !SAVEPIX);
  write_line (row1, col1+1, emsg, WHITE, !SAVEPIX);
  draw_shadow (widget, row1, col1, row2, col2, !SAVEPIX);
  g_timeout_add (GTK_TIME_DELAY, rweb_delay, widget);
}

static gint rweb_delay(gpointer widget)
{
  play_bells (DUPE_SOUND);
  sleep(5);
  gtk_main_quit ();
  return FALSE;
}

static void fatal_error_box(GtkWidget *widget, const gchar *emsg)
{
  GdkRectangle update_rect;
  gint lemsg, col1, col2;
  gint row1=19, row2=21;

  gdk_window_process_updates (main_window->window, TRUE);
  lemsg = strlen(emsg);
  col1 = 38-lemsg/2;
  col2 = col1+lemsg+3;
  update_rect.x = col1*wcol;
  update_rect.y = row1*hrow;
  update_rect.width = (col2-col1-1)*wcol;
  update_rect.height = (row2-row1-1)*hrow;
  draw_box (row1, col1, row2, col2, 1, WHITE, HI_RED,
            "", WHITE, "", LT_GRAY, !SAVEPIX);
  draw_rectangle (&update_rect, HI_RED, !SAVEPIX);
  write_line (row1, col1+1, emsg, WHITE, !SAVEPIX);
  draw_shadow (widget, row1, col1, row2, col2, !SAVEPIX);
  isel_contest = -1;
  g_timeout_add (GTK_TIME_DELAY, feb_delay, widget);
}

static gint feb_delay(gpointer widget)
{
  play_bells (BAD_KEY_SOUND);
  sleep(5);
  gtk_widget_destroy (main_window);
  return FALSE;
}

static void menu_bar(GtkWidget *widget)
{
  GdkRectangle update_rect;
  const gchar *mbfk[3] = {"F1        F2        F3        F4",
                          "F5        F6        F7        F8",
                          "F9        F10       F11       F12"};
  const gchar *mbsk[3] = {"S1        S2        S3        S4",
                          "S5        S6        S7        S8",
                          "S9        S10       S11       S12"};
  const gchar *mbak[3] = {"B         D         E",
                          "G         I         K",
                          "L         O         S"};
  const gchar *mbaw[3] = {" eam       elete     dit",
                          " oto       nitial    nowledge",
                          " og        utput     et"};
  const gchar *mbaw_ss[3] = {" eam       elete     dit",
                             " oto       nitial    nowledge",
                             " og        utput     et"};
  const gchar *mbfw[NUMBER_OF_CONTESTS][3] = {
   [DX] = {"  summary   cou/con   on/off    n/a     ",
           "  creader   info-6    n/a       packet  ",
           "  qsy        home      notes     update "},
   [WPX]= {"  summary   cou/con   on/off    prefix  ",
           "  creader   info-6    n/a       packet  ",
           "  qsy        home      notes     update "},
   [FD] = {"  summary   section   on/off    chgmode ",
           "  creader   info-6    who       packet  ",
           "  qsy        home      notes     update "},
   [WAE]= {"  summary   cou/con   on/off    n/a     ",
           "  creader   info-6    n/a       packet  ",
           "  qsy        home      notes     update "},
   [NYQP]={"  summary   county    on/off    chgmode ",
           "  creader   info-6    who       packet  ",
           "  qsy        home      notes     update "},
   [WW] = {"  summary   cou/con   on/off    cou/zon ",
           "  creader   info-6    zone-6    packet  ",
           "  qsy        home      notes     update "},
   [SS] = {"  summary   section   on/off    n/a     ",
           "  creader   info-6    who       packet  ",
           "  qsy        home      notes     update "},
   [A160]={"  summary   cou/con   on/off    n/a     ",
           "  creader   info-2    who       packet  ",
           "  section    home      notes     update "},
   [TEN]= {"  summary   cou/con   on/off    chgmode ",
           "  creader   info-2    who       packet  ",
           "  state      home      notes     update "},
   [WAA]= {"  summary   state     on/off    chgmode ",
           "  creader   info-6    n/a       packet  ",
           "  qsy        home      notes     update "}
  };
  const gchar *mbna="n/a    ";
  gchar mb_line[71];
  gint i, j;
  gint row1=1, col1=1, row2=3, col2=80, col1a=41;

  update_rect.x = (col1-1)*wcol;
  update_rect.y = (row1-1)*hrow;
  update_rect.width = (col2-col1+1)*wcol;
  update_rect.height = (row2-row1+1)*hrow;
  draw_rectangle (&update_rect, LT_GRAY, SAVEPIX);
  for(i=0; i<3; i++)
   write_line (row1-1+i, col1a-1, mbak[i], BLUE, SAVEPIX);
  if(shift_fkeys)
   for(i=0; i<3; i++)
    write_line (row1-1+i, col1-1, mbsk[i], RED, SAVEPIX);
  else
   for(i=0; i<3; i++)
    write_line (row1-1+i, col1-1, mbfk[i], BLUE, SAVEPIX);
  for(i=0; i<3; i++)
   {
    strcpy(mb_line, mbfw[isel_contest][i]);
    if(i==1)
     switch (isel_contest)
      {
       case FD :
       case NYQP :
       case A160 :
       case TEN :
       case WAA :
        break;
       default :
        if(mode!=CW)
         for(j=0; j<7; j++)
          mb_line[j+2] = mbna[j];
      }
    if(isel_contest==SS)
     strcat(mb_line, mbaw_ss[i]);
    else
     strcat(mb_line, mbaw[i]);
    write_line (row1-1+i, col1-1, mb_line, DK_GRAY, SAVEPIX);
   }
  write_line (row1+1, 71, mode_char[mode], RED, SAVEPIX);
  write_line (row1+1, 74, bandf[iband], RED, SAVEPIX);
  write_line (row1+1, 77, "MHz", RED, SAVEPIX);
  gtk_widget_queue_draw_area (widget,
                              update_rect.x,
                              update_rect.y,
                              update_rect.width,
                              update_rect.height);
  network_message_box (widget, "", !CLEAR);
}

static void date_and_time_bar(gpointer widget)
{
  GdkRectangle update_rect;
  gint row_date=1, col_date=69, row_time=2, col_time=73;
  gchar time_line[9], date_line[13];

  strftime(date_line, sizeof(date_line), "%a %m-%d-%g", &kb_time);
  strftime(time_line, sizeof(time_line), "%H:%M:%S", &kb_time);
  update_rect.x = (col_date-1)*wcol;
  update_rect.y = (row_date-1)*hrow;
  update_rect.width = (NUMBER_OF_COLUMNS-col_date+1)*wcol;
  update_rect.height = hrow;
  draw_rectangle (&update_rect, LT_GRAY, SAVEPIX);
  write_line (row_date-1, col_date-1, date_line, BLUE, SAVEPIX);
  gtk_widget_queue_draw_area (widget, 
                              update_rect.x,
                              update_rect.y,
                              update_rect.width,
                              update_rect.height);
  update_rect.x = (col_time-1)*wcol;
  update_rect.y = (row_time-1)*hrow;
  update_rect.width = (NUMBER_OF_COLUMNS-col_time+1)*wcol;
  update_rect.height = hrow;
  draw_rectangle (&update_rect, LT_GRAY, SAVEPIX);
  write_line (row_time-1, col_time-1, time_line, BLUE, SAVEPIX);
  gtk_widget_queue_draw_area (widget, 
                              update_rect.x,
                              update_rect.y,
                              update_rect.width,
                              update_rect.height);
}

static void cyan_bar_titles(GtkWidget *widget)
{
  GdkRectangle update_rect;
  const gchar *cbtw[NUMBER_OF_CONTESTS][2] = {
   [DX] = {"Qso# Freq On/Off ^^^  Utc    Sent  ",
           "Call Sign     Received     Multipliers    Pts"},
   [WPX]= {"Freq On/Off ^^^  Utc    Sent Qso#  ",
           "Call Sign     Received     Multipliers    Pts"},
   [FD] = {"Qso# Freq Mode   ^^^  Utc    Sent  ",
           "Call Sign     TxClass      Section        Pts"},
   [WAE]= {"Freq On/Off ^^^  Utc    Sent Qso#  ",
           "Call Sign     Received     Multipliers    Pts"},
   [NYQP]={"Qso# Freq Mode   ^^^  Utc    Sent  ",
           "Call Sign     Received     Multipliers    Pts"},
   [WW] = {"Qso# Freq On/Off ^^^  Utc    Sent  ",
           "Call Sign     Received     Multipliers    Pts"},
   [SS] = {"Freq On/Off ^^^  Utc    Sent Qso#  ",
           "Call Sign     Rcvd# Pr  Ck    Section     Pts"},
   [A160]={"Qso# Mode On/Off ^^^  Utc    Sent  ",
           "Call Sign     Received     Multipliers    Pts"},
   [TEN]= {"Qso# Mode On/Off ^^^  Utc    Sent  ",
           "Call Sign     Received     Multipliers    Pts"},
   [WAA]= {"Qso# Freq Mode   ^^^  Utc    Sent  ",
           "Call Sign     Received1    Received2      Pts"}
  };
  gint i;
  gchar cbt_line[81], *inspt;
  gint row1=25, col1=1, row2=25, col2=80;

  update_rect.x = (col1-1)*wcol;
  update_rect.y = (row1-1)*hrow;
  update_rect.width = (col2-col1+1)*wcol;
  update_rect.height = (row2-row1+1)*hrow;
  draw_rectangle (&update_rect, BLACK, SAVEPIX);
  strcpy(cbt_line, cbtw[isel_contest][0]);
  strcat(cbt_line, cbtw[isel_contest][1]);
  inspt = strstr(cbt_line, "^^^");
  for(i=0; i<3; i++)
   {
    *inspt = month_array[kb_time.tm_mon][i];
    inspt++;
   }
  write_line (row1-1, col1-1, cbt_line, CYAN, SAVEPIX);
  gtk_widget_queue_draw_area (widget,
                              update_rect.x,
                              update_rect.y,
                              update_rect.width,
                              update_rect.height);
  if(qued.inq)
   cyan_bar_que (widget);
}

static void black_bar(GtkWidget *widget, gint row1, gint col1,
                      gint row2, gint col2)
{
  GdkRectangle update_rect;
  
  update_rect.x = (col1-1)*wcol;
  update_rect.y = (row1-1)*hrow;
  update_rect.width = (col2-col1+1)*wcol;
  update_rect.height = (row2-row1+1)*hrow;
  draw_rectangle (&update_rect, BLACK, SAVEPIX);
  gtk_widget_queue_draw_area (widget,
                              update_rect.x,
                              update_rect.y,
                              update_rect.width,
                              update_rect.height);
}

static void color_bar(GtkWidget *widget, gint row1, gint col1,
                      gint row2, gint col2, gint bar_color)
{
  GdkRectangle update_rect;
  
  update_rect.x = (col1-1)*wcol;
  update_rect.y = (row1-1)*hrow;
  update_rect.width = (col2-col1+1)*wcol;
  update_rect.height = (row2-row1+1)*hrow;
  draw_rectangle (&update_rect, bar_color, SAVEPIX);
  gtk_widget_queue_draw_area (widget,
                              update_rect.x,
                              update_rect.y,
                              update_rect.width,
                              update_rect.height);
}

static void output_box(gint idraw)
{
  GdkRectangle update_rect;
  gint i, obi_color, udac;
  static OBVars obd;
  gint first_draw=FALSE;
  gint row1=4, col1=38, row2=11, col2=73;
  const gchar *title = "Output Functions";
  const gchar *subtitle = "Select:   Run:Enter Exit:Esc";
  const gchar *output_box_items[6] =
   {"Print Summary Sheet", "Print Dupe Sheets",
    "Print Log Sheets", "Write E-Mail Files to Hard Disk",
    "Write Backup File to Floppy Disk", "Write Backup File to USB Stick"};

  update_rect.x = col1*wcol;
  update_rect.y = row1*hrow;
  update_rect.width = (col2-col1-1)*wcol;
  update_rect.height = (row2-row1-1)*hrow;
  obd.number_of_items = 6;
  if(idraw)
   {
    if(main_cursor_type != CURSOR_OFF)
     {
      first_draw = TRUE;
      idisplay_type = IDT_SUMMARY;
      ireset_display = FALSE;
      update_display (main_drawing_area, REDRAW);
      main_cursor_type = CURSOR_OFF;
      ialt_box = 'O';
      obd.item = 0;
      g_signal_handler_block (main_window, main_key_handler_id);
      obd.key_handler_id = g_signal_connect (G_OBJECT (main_window),
                           "key_press_event",
                           G_CALLBACK (ob_key_handler), &obd);
     }
    draw_box (row1, col1, row2, col2, 1, LT_GRAY, ORANGE,
              title, WHITE, subtitle, LT_GRAY, SAVEPIX);
    udac = (col2-col1-strlen(subtitle))/2+col1+kb_index (subtitle, ":")+1;
    draw_updn_arrows (row2, udac, LT_GRAY);
    draw_shadow (main_drawing_area, row1, col1, row2, col2, SAVEPIX);
   }
  draw_rectangle (&update_rect, ORANGE, SAVEPIX);
  for(i=0; i<obd.number_of_items; i++)
   {
    if(i==obd.item)
     obi_color = YELLOW;
    else
     obi_color = BLACK;
    write_line (row1+i, col1+1, output_box_items[i], obi_color, 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);
  if(first_draw) gtk_main ();
}

static gint ob_key_handler(GtkWidget *widget, GdkEventKey *event,
                           gpointer data)
{
  OBVars *obd;
  gint icopy;
  gchar msg[43], email_file_names[5][13], lpr_line[81];
  gint margin=9;

#ifdef BSD
  const gchar *lpr_cmd =
         "lpr ";
#else
  const gchar *lpr_cmd =
         "lpr -r -o page-top=36 -o page-left=18 -o page-bottom=36 ";
#endif

  const gchar *print_file_names[4] = {"PRINT.SUM", "PRINT.DUP",
                                      "PRINT.LOG", "PRINT.MLT"};
  const gchar *media_msg[2] = {"To Floppy Disk", "To USB Stick"};

  obd = (OBVars*)data;
  switch (event->keyval)
   {
    case 65362 : /*up_arrow*/
     obd->item--;
     if(obd->item<0)
      obd->item = obd->number_of_items-1;
     output_box (!REDRAW);
     break;
    case 65364 : /*down_arrow*/
     obd->item++;
     if(obd->item>obd->number_of_items-1)
      obd->item = 0;
     output_box (!REDRAW);
     break;
    case 65293 : /*enter*/
     switch (obd->item)
      {
       case 0 :
        if(icall_count)
         {
          write_summary_file (print_file_names[obd->item], margin);
          strcpy(lpr_line, lpr_cmd);
          strcat(lpr_line, print_file_names[obd->item]);
          icopy = system(lpr_line);
          if(isel_contest==WPX)
           {
            write_multiplier_file (print_file_names[3], margin);
            strcpy(lpr_line, lpr_cmd);
            strcat(lpr_line, print_file_names[3]);
            icopy = system(lpr_line);
           }
          if(!icopy)
           {
            play_bells (MESSAGE_SOUND);
            if(isel_contest==WPX)
             {
              strcpy(msg, "Prefix Sheet Sent to Printer");
              message_box (main_drawing_area, msg, !REDRAW, CLEAR);
             }
            strcpy(msg, "Summary Sheet Sent to Printer");
            message_box (main_drawing_area, msg, !REDRAW, isel_contest!=WPX);
           }
          else
           {
            play_bells (DUPE_SOUND);
            strcpy(msg, "Printer Error!");
            message_box (main_drawing_area, msg, !REDRAW, CLEAR);
           }
         }
        else
         {
          play_bells (MESSAGE_SOUND);
          strcpy(msg, "No Calls in Log!");
          message_box (main_drawing_area, msg, !REDRAW, CLEAR);
          strcpy(msg, "Summary Sheet Not Printed!");
          message_box (main_drawing_area, msg, !REDRAW, !CLEAR);
         }
        output_box (REDRAW);
        break;
       case 1 :
        if(icall_count)
         {
          write_dupe_file (print_file_names[obd->item], margin);
          strcpy(lpr_line, lpr_cmd);
          strcat(lpr_line, print_file_names[obd->item]);
          icopy = system(lpr_line);
          if(!icopy)
           {
            play_bells (MESSAGE_SOUND);
            strcpy(msg, "Dupe Sheets Sent to Printer");
            message_box (main_drawing_area, msg, !REDRAW, CLEAR);
           }
          else
           {
            play_bells (DUPE_SOUND);
            strcpy(msg, "Printer Error!");
            message_box (main_drawing_area, msg, !REDRAW, CLEAR);
           }
         }
        else
         {
          play_bells (MESSAGE_SOUND);
          strcpy(msg, "No Calls in Log!");
          message_box (main_drawing_area, msg, !REDRAW, CLEAR);
          strcpy(msg, "Dupe Sheets Not Printed!");
          message_box (main_drawing_area, msg, !REDRAW, !CLEAR);
         }
        output_box (REDRAW);
        break;
       case 2 :
        if(icall_count)
         {
          write_log_file (print_file_names[obd->item], margin);
          strcpy(lpr_line, lpr_cmd);
          strcat(lpr_line, print_file_names[obd->item]);
          icopy = system(lpr_line);
          if(!icopy)
           {
            play_bells (MESSAGE_SOUND);
            strcpy(msg, "Log Sheets Sent to Printer");
            message_box (main_drawing_area, msg, !REDRAW, CLEAR);
           }
          else
           {
            play_bells (DUPE_SOUND);
            strcpy(msg, "Printer Error!");
            message_box (main_drawing_area, msg, !REDRAW, CLEAR);
           }
         }
        else
         {
          play_bells (MESSAGE_SOUND);
          strcpy(msg, "No Calls in Log!");
          message_box (main_drawing_area, msg, !REDRAW, CLEAR);
          strcpy(msg, "Log Sheets Not Printed!");
          message_box (main_drawing_area, msg, !REDRAW, !CLEAR);
         }
        output_box (REDRAW);
        break;
       case 3 :
        if(icall_count)
         {
          write_email_files (email_file_names);
          strcpy(msg, email_file_names[2]);
          if(isel_contest==WPX)
           {
            strcat(msg, " ");
            strcat(msg, email_file_names[3]);
           }
          message_box (main_drawing_area, msg, !REDRAW, CLEAR);
          strcpy(msg, email_file_names[0]);
          strcat(msg, " ");
          strcat(msg, email_file_names[1]);
          message_box (main_drawing_area, msg, !REDRAW, !CLEAR);
          strcpy(msg, "E-mail Files Written:");
          strcat(msg, email_file_names[4]);
          message_box (main_drawing_area, msg, !REDRAW, !CLEAR);
         }
        else
         {
          strcpy(msg, "No Calls in Log!");
          message_box (main_drawing_area, msg, !REDRAW, CLEAR);
          strcpy(msg, "E-mail Files Not Written!");
          message_box (main_drawing_area, msg, !REDRAW, !CLEAR);
         }
        play_bells (MESSAGE_SOUND);
        output_box (REDRAW);
        break;
       case 4 :
       case 5 :
        if(!backup_to_media (obd->item))
         {
          play_bells (MESSAGE_SOUND);
          strcpy(msg, media_msg[obd->item-4]);
          message_box (main_drawing_area, msg, !REDRAW, CLEAR);
          strcpy(msg, "Backup File Written");
          message_box (main_drawing_area, msg, !REDRAW, !CLEAR);
         }
        else
         {
          play_bells (DUPE_SOUND);
          strcpy(msg, "Error Writing ");
          strcat(msg, media_msg[obd->item-4]);
          strcat(msg, "!");
          message_box (main_drawing_area, msg, !REDRAW, CLEAR);
         }
        output_box (REDRAW);
      }
     break;
    case 65307 : /*escape*/
     g_signal_handler_disconnect (main_window, obd->key_handler_id);
     g_signal_handler_unblock (main_window, main_key_handler_id);
     gtk_main_quit ();
     main_cursor_type = LINE_CURSOR;
     update_display (main_drawing_area, REDRAW);
     ialt_box = FALSE;
     break;
    default :
     play_bells (BAD_KEY_SOUND);
   }
  return TRUE;
}

static gint backup_to_media(gint item)
{
  gchar msg[43], media_dir[129];
  gint imount=FALSE, icopy=TRUE;

#ifdef BSD
  struct stat statbuf;
  const gchar *mntd="kb_mnt";
  const gchar *media_path[2] = {"/dev/fd0", "/dev/da0s1"};
#else
  int iread, iwrite, fd_fifos[2];
  char line_in[2];
  const char *fifos[2] = {"/opt/kb/kbfifo_wtv", "/opt/kb/kbfifo_rfv"};
  const gchar *media_path[2] = {"/media/floppy", "/media/disk"};
#endif

  if(item<4 || item>5)
   return icopy;

#ifdef BSD
  if(stat(mntd, &statbuf))
   mkdir(mntd, 0770);
  strcpy(msg, "mount -t msdosfs ");
  strcat(msg, media_path[item-4]);
  strcat(msg, " ");
  strcat(msg, mntd);
  imount = system(msg);
  if(imount)
   imount = check_mtab_file (media_path[item-4], media_dir);
  if(!imount)
   {
    strcpy(msg, "cp ");
    strcat(msg, contest_file_name);
    strcat(msg, " ");
    strcat(msg, mntd);
    strcat(msg, "/");
    strcat(msg, contest_file_name);
    icopy = system(msg);
    strcpy(msg, "umount ");
    strcat(msg, mntd);
    system(msg);
    rmdir(mntd);
   }
#else
  if(item==4 && get_running_pid ("kb_mountf")>-1)
   {
    memset(line_in, '\0', sizeof(line_in));
    if((fd_fifos[0] = open(fifos[0], O_WRONLY))==-1)
     return icopy;
    iwrite = write(fd_fifos[0], "m", 1);
    if((fd_fifos[1] = open(fifos[1], O_RDONLY))==-1)
     {
      close(fd_fifos[0]);
      return icopy;
     }
    iread = read(fd_fifos[1], line_in, 1);
    switch (line_in[0])
     {
      case 'a' :
      case 's' :
       strcpy(msg, "cp ");
       strcat(msg, contest_file_name);
       strcat(msg, " ");
       strcat(msg, media_path[item-4]);
       strcat(msg, "/");
       strcat(msg, contest_file_name);
       icopy = system(msg);
       iwrite = write(fd_fifos[0], "u", 1);
       close(fd_fifos[0]);
       iread = read(fd_fifos[1], line_in, 1);
       close(fd_fifos[1]);
       break;
      case 'f' :
       close(fd_fifos[0]);
       close(fd_fifos[1]);
       return icopy;
       break;
     }
   }
  else
   {
    strcpy(msg, "mount ");
    strcat(msg, media_path[item-4]);
    imount = system(msg);
    if(imount)
     imount = check_mtab_file (media_path[item-4], media_dir);
    if(!imount)
     {
      strcpy(msg, "cp ");
      strcat(msg, contest_file_name);
      strcat(msg, " ");
      strcat(msg, media_path[item-4]);
      strcat(msg, "/");
      strcat(msg, contest_file_name);
      icopy = system(msg);
      if(item==4)
       {
        strcpy(msg, "umount ");
        strcat(msg, media_path[item-4]);
        system(msg);
       }
     }
    else if(item==5)
     {
      imount = check_mtab_file ("vfat", media_dir);
      if(!imount)
       {
        strcpy(msg, "cp ");
        strcat(msg, contest_file_name);
        strcat(msg, " ");
        strcat(msg, media_dir);
        strcat(msg, "/");
        strcat(msg, contest_file_name);
        icopy = system(msg);
       }
     }
   }
#endif

  return icopy;
}

static gint check_mtab_file(const gchar *mp, gchar *mpd)
{
  FILE *fp;
  gchar mtab_line[129], mtab_hold[129];
  gint ims;
  gint cmf=TRUE;

  fp = fopen("/etc/mtab", "r");
  if(fp!=NULL)
   {
    for( ; ; )
     {
      fgets(mtab_line, sizeof(mtab_line), fp);
      if(feof(fp)) break;
      if(strcmp(mp, "vfat"))
       {
        if(kb_index (mtab_line, mp)>-1)
         {
          cmf = FALSE;
          break;
         }
       }
      else
       {
        if((ims = kb_index (mtab_line, "/media/"))>-1 &&
           kb_index (mtab_line, "floppy")<0)
         {
          concat(mtab_hold, mtab_line, ims, strlen(mtab_line), COPY);
          if((ims = kb_index (mtab_hold, " "))>6)
           {
            concat(mpd, mtab_hold, 0, ims-1, COPY);
            cmf = FALSE;
            break;
           }
         }
       }
     }
    fclose(fp);
   }
  return cmf;
}

static void update_box(gint idraw)
{
  GdkRectangle update_rect;
  gint i, ubi_color, udac;
  static OBVars ubd;
  gint first_draw=FALSE;
  gint row1=4, col1=18, row2=7, col2=53;
  const gchar *title = "Update Functions";
  const gchar *subtitle = "Select:   Run:Enter Exit:Esc";
  const gchar *update_box_items[2] = {"Call Library Data", "Radio Data"};

  update_rect.x = col1*wcol;
  update_rect.y = row1*hrow;
  update_rect.width = (col2-col1-1)*wcol;
  update_rect.height = (row2-row1-1)*hrow;
  ubd.number_of_items = 2;
  if(idraw)
   {
    if(main_cursor_type != CURSOR_OFF)
     {
      first_draw = TRUE;
      idisplay_type = IDT_SUMMARY;
      ireset_display = FALSE;
      update_display (main_drawing_area, REDRAW);
      main_cursor_type = CURSOR_OFF;
      ialt_box = 'U';
      ubd.item = 0;
      g_signal_handler_block (main_window, main_key_handler_id);
      ubd.key_handler_id = g_signal_connect (G_OBJECT (main_window),
                           "key_press_event",
                           G_CALLBACK (ub_key_handler), &ubd);
     }
    draw_box (row1, col1, row2, col2, 1, LT_GRAY, ORANGE,
              title, WHITE, subtitle, LT_GRAY, SAVEPIX);
    udac = (col2-col1-strlen(subtitle))/2+col1+kb_index (subtitle, ":")+1;
    draw_updn_arrows (row2, udac, LT_GRAY);
    draw_shadow (main_drawing_area, row1, col1, row2, col2, SAVEPIX);
   }
  draw_rectangle (&update_rect, ORANGE, SAVEPIX);
  for(i=0; i<ubd.number_of_items; i++)
   {
    if(i==ubd.item)
     ubi_color = YELLOW;
    else
     ubi_color = BLACK;
    write_line (row1+i, col1+1, update_box_items[i], ubi_color, 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);
  if(first_draw) gtk_main ();
}

static gint ub_key_handler(GtkWidget *widget, GdkEventKey *event,
                           gpointer data)
{
  OBVars *ubd;
  gint iurf;
  gchar msg[43];
  
  ubd = (OBVars*)data;
  switch (event->keyval)
   {
    case 65362 : /*up_arrow*/
     ubd->item--;
     if(ubd->item<0)
      ubd->item = ubd->number_of_items-1;
     update_box (!REDRAW);
     break;
    case 65364 : /*down_arrow*/
     ubd->item++;
     if(ubd->item>ubd->number_of_items-1)
      ubd->item = 0;
     update_box (!REDRAW);
     break;
    case 65293 : /*enter*/
     switch (ubd->item)
      {
       case 0 :
        update_call_library_file ();
        strcpy(msg, "Call Library Updated");
        message_box (main_drawing_area, msg, !REDRAW, CLEAR);
        play_bells (MESSAGE_SOUND);
        break;
       case 1 :
        iurf = update_radio_file ();
        if(iurf==-1)
         strcpy(msg, "Radio Control is Not Active");
        else if(iurf==-2)
         strcpy(msg, "Radio Model is Not Updateable");
        else
         strcpy(msg, "Radio Data Updated");
        message_box (main_drawing_area, msg, !REDRAW, CLEAR);
        play_bells (MESSAGE_SOUND);
        break;
      }
     break;
    case 65307 : /*escape*/
     g_signal_handler_disconnect (main_window, ubd->key_handler_id);
     g_signal_handler_unblock (main_window, main_key_handler_id);
     gtk_main_quit ();
     main_cursor_type = LINE_CURSOR;
     update_display (main_drawing_area, REDRAW);
     ialt_box = FALSE;
     break;
    default :
     play_bells (BAD_KEY_SOUND);
   }
  return TRUE;
}

static void update_call_library_file(void)
{
  gint i;

  write_backup_file (clib.filnam);
  for(i=1; i<=icall_count; i++)
   if(strcmp(cr_array[call_tree.sort_order[i]].call,
      cr_array[call_tree.sort_order[i-1]].call))
    update_call_library (call_tree.sort_order[i]);
  remove_old_entries ();
  write_call_library_file ();
}

static gint update_radio_file(void)
{
  gint mb;
  gchar filnam[13], radio_liney[RADIO_LENGTHY];
  gint iurf=-1;

  if(fp_radio)
   {
    get_cat_filename (filnam);
    mb = 6*mode+iband;
    switch (radio_model)
     {
      case RM_FT1000 :
       iurf = -2;
       break;
      case RM_FT950 :
      case RM_FT5000 :
       while(fgets(radio_liney, RADIO_LENGTHY, fp_radio));
       usleep(100000);
       fputs("CO00;", fp_radio);
       fflush(fp_radio);
       usleep(100000);
       fgets(rcs[1].co_onoff[mb], sizeof(rcs[1].co_onoff[mb]), fp_radio);
       usleep(100000);
       fputs("CO01;", fp_radio);
       fflush(fp_radio);
       usleep(100000);
       fgets(rcs[1].co_value[mb], sizeof(rcs[1].co_value[mb]), fp_radio);
       usleep(100000);
       fputs("NA0;", fp_radio);
       fflush(fp_radio);
       usleep(100000);
       fgets(rcs[1].na[mb], sizeof(rcs[1].na[mb]), fp_radio);
       usleep(100000);
       fputs("SH0;", fp_radio);
       fflush(fp_radio);
       usleep(100000);
       fgets(rcs[1].sh[mb], sizeof(rcs[1].sh[mb]), fp_radio);
       usleep(100000);
       fputs("IS0;", fp_radio);
       fflush(fp_radio);
       usleep(100000);
       fgets(rcs[1].is[mb], sizeof(rcs[1].is[mb]), fp_radio);
       usleep(100000);
       fputs("RF0;", fp_radio);
       fflush(fp_radio);
       usleep(100000);
       fgets(rcs[1].rf[mb], sizeof(rcs[1].rf[mb]), fp_radio);
       if(rcs[1].rf[mb][3]=='4' || rcs[1].rf[mb][3]=='5' ||
          rcs[1].rf[mb][3]=='6')
        rcs[1].rf[mb][3] = '0';
       usleep(100000);
       fputs("GT0;", fp_radio);
       fflush(fp_radio);
       usleep(100000);
       fgets(rcs[1].gt[mb], sizeof(rcs[1].gt[mb]), fp_radio);
       if(rcs[1].gt[mb][3]=='4' || rcs[1].gt[mb][3]=='5' ||
          rcs[1].gt[mb][3]=='6')
        rcs[1].gt[mb][3] = '4';
       usleep(100000);
       fputs("RA0;", fp_radio);
       fflush(fp_radio);
       usleep(100000);
       fgets(rcs[1].ra[mb], sizeof(rcs[1].ra[mb]), fp_radio);
       usleep(100000);
       fputs("PA0;", fp_radio);
       fflush(fp_radio);
       usleep(100000);
       fgets(rcs[1].pa[mb], sizeof(rcs[1].pa[mb]), fp_radio);
       write_radio_file (filnam, 1);
       iurf = 0;
       break;
      default :
       iurf = -2;
       break;
     }
   }
  return iurf;
}

static void goto_box(gint idraw)
{
  GdkRectangle update_rect, ur_field;
  gint i, gbi_color, udac;
  static GBVars gbd = {
   .number_of_items = 4, .field_length = {4, 13, 6, 0},
   .col1 = {48, 39, 46, 0}, .cursor_col = 0, .field_line = ""};
  gint first_draw=FALSE;
  gint row1=4, col1=25, row2=9, col2=60;
  const gchar *title = "Go to Place in Log by:";
  const gchar *subtitle = "Select:   Run:Enter Exit:Esc";
  const gchar *goto_box_items[4] =
   {"QSO Number           ____", "Call Sign   _____________",
    "Date/Time (DDHHMM) ______", "Unknown Country"};

  update_rect.x = col1*wcol;
  update_rect.y = row1*hrow;
  update_rect.width = (col2-col1-1)*wcol;
  update_rect.height = (row2-row1-1)*hrow;
  gbd.row1 = row1+1;
  if(idraw)
   {
    if(main_cursor_type != CURSOR_OFF)
     {
      first_draw = TRUE;
      idisplay_type = IDT_SUMMARY;
      ireset_display = FALSE;
      update_display (main_drawing_area, REDRAW);
      main_cursor_type = CURSOR_OFF;
      ialt_box = 'G';
      gbd.item = 0;
      gbd.cursor_col = gbd.col1[0];
      gbd.done = FALSE;
      g_signal_handler_block (main_window, main_key_handler_id);
      gbd.key_handler_id = g_signal_connect (G_OBJECT (main_window),
                           "key_press_event",
                           G_CALLBACK (gb_key_handler), &gbd);
      g_timeout_add (250, gb_cursor, &gbd);
     }
    draw_box (row1, col1, row2, col2, 1, LT_GRAY, ORANGE,
              title, WHITE, subtitle, LT_GRAY, SAVEPIX);
    udac = (col2-col1-strlen(subtitle))/2+col1+kb_index (subtitle, ":")+1;
    draw_updn_arrows (row2, udac, LT_GRAY);
    draw_shadow (main_drawing_area, row1, col1, row2, col2, SAVEPIX);
   }
  draw_rectangle (&update_rect, ORANGE, SAVEPIX);
  for(i=0; i<gbd.number_of_items; i++)
   {
    if(i==gbd.item)
     {
      gbi_color = YELLOW;
      ur_field.x = (gbd.col1[i]-1)*wcol;
      ur_field.y = (row1+i)*hrow;
      ur_field.width = gbd.field_length[i]*wcol;
      ur_field.height = hrow;
     }
    else
     gbi_color = BLACK;
    write_line (row1+i, col1+1, goto_box_items[i], gbi_color, SAVEPIX);
    if(i==gbd.item && i<3)
     {
      if(insert_mode)
       draw_rectangle (&ur_field, YELLOW, SAVEPIX);
      else
       draw_rectangle (&ur_field, BLACK, 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);
  if(first_draw) gtk_main ();
}

static gint gb_key_handler(GtkWidget *widget, GdkEventKey *event,
                           gpointer data)
{
  GBVars *gbd;
  ESVars esd;
  gint i, fl_error;
  guint ikey, istate;
  gchar msg[43], dhm[7], dd[3], hh[3], mm[3];
  static gint isf=0;
  
  gbd = (GBVars*)data;
  ikey = toupper_ui(event->keyval);
  istate = event->state;
  esd.ikey = ikey;
  esd.cursor_row = gbd->row1+gbd->item;
  esd.cursor_colp = &gbd->cursor_col;
  esd.field_col = gbd->col1[gbd->item];
  esd.field_length = gbd->field_length[gbd->item];
  esd.field_linep = gbd->field_line;
  switch (ikey)
   {
    case 65505 : /*left shift*/
    case 65506 : /*right shift*/
    case 65509 : /*caps lock*/
    case 65407 : /*num lock*/
    case 65513 : /*left alt*/
    case 65514 : /*right alt*/
     break;
    case 65361 : /*left_arrow*/
    case 65363 : /*right_arrow*/
    case 65360 : /*home*/
    case 65367 : /*end*/
    case 65535 : /*delete*/
    case 65288 : /*backspace*/
     if(gbd->item!=3)
      edit_line (&esd);
     else
      play_bells (BAD_KEY_SOUND);
     break;
    case 65379 : /*insert*/
     if(gbd->item!=3)
      {
       insert_mode = !insert_mode;
       edit_line (&esd);
      }
     else
      play_bells (BAD_KEY_SOUND);
     break;
    case 65362 : /*up_arrow*/
     gbd->item--;
     if(gbd->item<0)
      gbd->item = gbd->number_of_items-1;
     strcpy(gbd->field_line, "");
     gbd->cursor_col = gbd->col1[gbd->item]+strlen(gbd->field_line);
     goto_box (!REDRAW);
     isf = 0;
     break;
    case 65364 : /*down_arrow*/
     gbd->item++;
     if(gbd->item>gbd->number_of_items-1)
      gbd->item = 0;
     strcpy(gbd->field_line, "");
     gbd->cursor_col = gbd->col1[gbd->item]+strlen(gbd->field_line);
     goto_box (!REDRAW);
     isf = 0;
     break;
    case 65293 : /*enter*/
     switch (gbd->item)
      {
       case 0 :
        isf = atoi(gbd->field_line);
        for(i=0; i<strlen(gbd->field_line); i++)
         if(!isdigit(gbd->field_line[i]))
          {
           isf = 0;
           break;
          }
        if(isf && isf<=icall_count)
         {
          iscroll_log = isf-1;
          scroll_log (main_drawing_area);
          cyan_bar (main_drawing_area);
          message_box (main_drawing_area, "", !REDRAW, CLEAR);
         }
        else
         {
          play_bells (MESSAGE_SOUND);
          strcpy(msg, "Invalid Qso Number!");
          message_box (main_drawing_area, msg, !REDRAW, CLEAR);
         }
        goto_box (REDRAW);
        edit_line (&esd);
        break;
       case 1 :
        for(i=isf+1; i<=icall_count+1; i++)
         if(!strcmp(cr_array[i].call, gbd->field_line) &&
            i!=icall_count+1)
          {
           isf = i;
           break;
          }
        if(isf && i<=icall_count)
         {
          iscroll_log = isf-1;
          scroll_log (main_drawing_area);
          cyan_bar (main_drawing_area);
          message_box (main_drawing_area, "", !REDRAW, CLEAR);
         }
        else
         {
          play_bells (MESSAGE_SOUND);
          strcpy(msg, "With Specified Call Sign");
          message_box (main_drawing_area, msg, !REDRAW, CLEAR);
          if(!isf)
           strcpy(msg, "No Entries Found");
          else
           strcpy(msg, "No More Entries Found");
          message_box (main_drawing_area, msg, !REDRAW, !CLEAR);
          isf = 0;
          iscroll_log = icall_count;
          scroll_log (main_drawing_area);
          cyan_bar (main_drawing_area);
         }
        goto_box (REDRAW);
        edit_line (&esd);
        break;
       case 2 :
        fl_error = FALSE;
        if(strlen(gbd->field_line)!=6)
         fl_error = TRUE;
        if(!fl_error)
         {
          for(i=0; i<strlen(gbd->field_line); i++)
           if(!isdigit(gbd->field_line[i]))
            {
             fl_error = TRUE;
             break;
            }
         }
        if(!fl_error)
         {
          concat(dd, gbd->field_line, 0, 1, COPY);
          concat(hh, gbd->field_line, 2, 3, COPY);
          concat(mm, gbd->field_line, 4, 5, COPY);
          if(atoi(dd)<1 || atoi(dd)>31 || atoi(hh)>23 || atoi(mm)>59)
           fl_error = TRUE;
         }
        if(!fl_error)
         {
          for(i=isf+1; i<=icall_count+1; i++)
           {
            concat(dhm, cr_array[i].date, 2, 3, COPY);
            concat(dhm, cr_array[i].time, 0, 1, !COPY);
            concat(dhm, cr_array[i].time, 2, 3, !COPY);
            if(!strcmp(dhm, gbd->field_line))
             {
              isf = i;
              break;
             }
            }
          if(isf && i<=icall_count)
           {
            iscroll_log = isf-1;
            scroll_log (main_drawing_area);
            cyan_bar (main_drawing_area);
            message_box (main_drawing_area, "", !REDRAW, CLEAR);
           }
          else
           {
            play_bells (MESSAGE_SOUND);
            strcpy(msg, "With Specified Date/Time");
            message_box (main_drawing_area, msg, !REDRAW, CLEAR);
            if(!isf)
             strcpy(msg, "No Entries Found");
            else
             strcpy(msg, "No More Entries Found");
            message_box (main_drawing_area, msg, !REDRAW, !CLEAR);
            isf = 0;
            iscroll_log = icall_count;
            scroll_log (main_drawing_area);
            cyan_bar (main_drawing_area);
           }
         }
        else
         {
          isf = 0;
          play_bells (MESSAGE_SOUND);
          strcpy(msg, "Invalid Date/Time!");
          message_box (main_drawing_area, msg, !REDRAW, CLEAR);
         }
        goto_box (REDRAW);
        edit_line (&esd);
        break;
       case 3 :
        for(i=isf+1; i<=icall_count+1; i++)
         if(!strcmp(cr_array[i].rec_county, countries.country_abv[0]))
          {
           isf = i;
           break;
          }
        if(isf && i<=icall_count)
         {
          iscroll_log = isf-1;
          scroll_log (main_drawing_area);
          cyan_bar (main_drawing_area);
          message_box (main_drawing_area, "", !REDRAW, CLEAR);
         }
        else
         {
          play_bells (MESSAGE_SOUND);
          strcpy(msg, "With Unknown Country");
          message_box (main_drawing_area, msg, !REDRAW, CLEAR);
          if(!isf)
           strcpy(msg, "No Entries Found");
          else
           strcpy(msg, "No More Entries Found");
          message_box (main_drawing_area, msg, !REDRAW, !CLEAR);
          isf = 0;
          iscroll_log = icall_count;
          scroll_log (main_drawing_area);
          cyan_bar (main_drawing_area);
         }
        goto_box (REDRAW);
        break;
      }
     break;
    case 65307 : /*escape*/
     gbd->done = TRUE;
     strcpy(gbd->field_line, "");
     if(strcmp(set_screen_choices[2], yn_bracket[1]))
      {
       iscroll_log = icall_count;
       search_tree (icall_count, icall_count);
      }
     main_cursor_type = LINE_CURSOR;
     ialt_box = FALSE;
     break;
    default :
     if(isupper_ui(ikey) || isdigit_ui(ikey) || ikey=='/')
      {
       if(istate==24) /*alt-keys*/
        {
         if(ikey=='D')
          {
           g_signal_handler_block (main_window, gbd->key_handler_id);
           process_delete_command (main_drawing_area);
           g_signal_handler_unblock (main_window, gbd->key_handler_id);
           main_cursor_type = CURSOR_OFF;
           ialt_box = 'G';
           goto_box (REDRAW);
           esd.ikey = 65293; /*enter*/
           edit_line (&esd);
          }
         else if(ikey=='E')
          {
           g_signal_handler_block (main_window, gbd->key_handler_id);
           main_cursor_type = LINE_CURSOR;
           process_edit_command (main_drawing_area);
           g_signal_handler_unblock (main_window, gbd->key_handler_id);
           main_cursor_type = CURSOR_OFF;
           goto_box (REDRAW);
           esd.ikey = 65293; /*enter*/
           edit_line (&esd);
          }
         else
          play_bells (BAD_KEY_SOUND);
        }
       else if(gbd->item!=3)
        edit_line (&esd);
       else
        play_bells (BAD_KEY_SOUND);
      }
     else
      play_bells (BAD_KEY_SOUND);
   }
  return TRUE;
}

static gint gb_cursor(gpointer data)
{
  GBVars *gbd;
  ESVars esd;
  gint cursor_fg_color, cursor_bg_color;
  static gint iadd = 0;

  gbd = (GBVars*)data;
  if(gbd->done)
   {
    g_signal_handler_disconnect (main_window, gbd->key_handler_id);
    g_signal_handler_unblock (main_window, main_key_handler_id);
    gtk_main_quit ();
    update_display (main_drawing_area, REDRAW);
    if(insert_mode)
     {
      esd.ikey = 65379;
      esd.cursor_row = cbv.cursor_row;
      esd.cursor_colp = &cbv.cursor_col;
      esd.field_col = cbv.col1[cbv.item];
      esd.field_length = cbv.field_length[cbv.item];
      set_esd_flp (icall_count+1, &esd);
      edit_line (&esd);
     }
    return FALSE;
   }
  if(gbd->item<3 && !ialt_de)
   {
    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, LINE_CURSOR,
                    gbd->row1+gbd->item, gbd->cursor_col,
                    cursor_fg_color, cursor_bg_color);
   }
  return TRUE;
}

static gint enter_zone_box(void)
{
  GdkRectangle update_rect;
  static SMBVars ezbd = {
   .field_length = 2, .col1 = 51, .cursor_col = 0};
  gint row1=21, col1=50, row2=23, col2=63;
  gint idraw=TRUE;
  const gchar *title = "Enter Zone";
  const gchar *subtitle = "Run:Enter";

  ialt_box = 'M';
  if(mode==CW)
   {
    col1++;
    ezbd.col1++;
   }
  update_rect.x = col1*wcol;
  update_rect.y = row1*hrow;
  update_rect.width = (col2-col1-1)*wcol;
  update_rect.height = (row2-row1-1)*hrow;
  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+1, row1+1, col2-1);
  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);
  ezbd.row1 = row1+1;
  ezbd.cursor_col = ezbd.col1;
  ezbd.done = FALSE;
  strcpy(ezbd.field_line, "");
  main_cursor_type = CURSOR_OFF;
  g_signal_handler_block (main_window, main_key_handler_id);
  ezbd.key_handler_id = g_signal_connect (G_OBJECT (main_window),
                        "key_press_event",
                        G_CALLBACK (ezb_key_handler), &ezbd);
  g_timeout_add (250, ezb_cursor, &ezbd);
  gtk_main ();
  g_signal_handler_disconnect (main_window, ezbd.key_handler_id);
  g_signal_handler_unblock (main_window, main_key_handler_id);
  main_cursor_type = LINE_CURSOR;
  update_display (main_drawing_area, REDRAW);
  ialt_box = FALSE;
  return atoi(ezbd.field_line);
}

static gint ezb_key_handler(GtkWidget *widget, GdkEventKey *event,
                            gpointer data)
{
  SMBVars *ezbd;
  ESVars esd;
  gint izn;
  guint ikey;
  
  ezbd = (SMBVars*)data;
  if(!ezbd->done)
   {
    ikey = event->keyval;
    esd.ikey = ikey;
    esd.cursor_row = ezbd->row1;
    esd.cursor_colp = &ezbd->cursor_col;
    esd.field_col = ezbd->col1;
    esd.field_length = ezbd->field_length;
    esd.field_linep = ezbd->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*/
      case 65421 : /*keypad enter*/
       izn = 0;
       if(strlen(ezbd->field_line))
        izn = atoi(ezbd->field_line);
       if(izn>0 && izn<41)
        ezbd->done = TRUE;
       else
        play_bells (BAD_KEY_SOUND);
       break;
      case 65307 : /*escape*/
       strcpy(ezbd->field_line, "");
       edit_line (&esd);
       break;
      default :
       if(isdigit_ui(ikey))
        edit_line (&esd);
       else
        play_bells (BAD_KEY_SOUND);
     }
   }
  else
   play_bells (BAD_KEY_SOUND);
  return TRUE;
}

static gint ezb_cursor(gpointer data)
{
  SMBVars *ezbd;
  gint cursor_fg_color, cursor_bg_color;
  static gint iadd = 0;

  ezbd = (SMBVars*)data;
  if(ezbd->done)
   {
    gtk_main_quit ();
    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, LINE_CURSOR,
                  ezbd->row1, ezbd->cursor_col,
                  cursor_fg_color, cursor_bg_color);
  return TRUE;
}
