Пример #1
0
/* render help dialog */
void
load_help_popup (WINDOW * main_win)
{
   int c, quit = 1;
   size_t i, n;
   int y, x, h = HELP_WIN_HEIGHT, w = HELP_WIN_WIDTH;
   int w2 = w - 2;

   n = ARRAY_SIZE (help_main);
   getmaxyx (stdscr, y, x);

   WINDOW *win = newwin (h, w, (y - h) / 2, (x - w) / 2);
   keypad (win, TRUE);
   wborder (win, '|', '|', '-', '-', '+', '+', '+', '+');

   /* create a new instance of GMenu and make it selectable */
   GMenu *menu = new_gmenu (win, HELP_MENU_HEIGHT, HELP_MENU_WIDTH, HELP_MENU_Y,
                            HELP_MENU_X);
   menu->size = n;

   /* add items to GMenu */
   menu->items = (GItem *) xcalloc (n, sizeof (GItem));
   for (i = 0; i < n; ++i) {
      menu->items[i].name = alloc_string (help_main[i]);
      menu->items[i].checked = 0;
   }
   post_gmenu (menu);

   draw_header (win, "GoAccess Quick Help", 1, 1, w2, 1);
   mvwprintw (win, 2, 2, "[UP/DOWN] to scroll - [q] to quit");

   wrefresh (win);
   while (quit) {
      c = wgetch (stdscr);
      switch (c) {
       case KEY_DOWN:
          gmenu_driver (menu, REQ_DOWN);
          draw_header (win, "", 2, 3, HELP_MENU_WIDTH, 0);
          break;
       case KEY_UP:
          gmenu_driver (menu, REQ_UP);
          draw_header (win, "", 2, 3, HELP_MENU_WIDTH, 0);
          break;
       case KEY_RESIZE:
       case 'q':
          quit = 0;
          break;
      }
      wrefresh (win);
   }
   /* clean stuff up */
   for (i = 0; i < n; ++i)
      free (menu->items[i].name);
   free (menu->items);
   free (menu);

   touchwin (main_win);
   close_win (win);
   wrefresh (main_win);
}
Пример #2
0
/* render an actual menu item */
static void
draw_menu_item (GMenu * menu, char *s, int x, int y, int w, int color,
                int checked)
{
  char check, *lbl = NULL;
  if (menu->selectable) {
    check = checked ? 'x' : ' ';
    lbl = xmalloc (snprintf (NULL, 0, "[%c] %s", check, s) + 1);
    sprintf (lbl, "[%c] %s", check, s);
    draw_header (menu->win, lbl, "%s", y, x, w, color, 0);
    free (lbl);
  } else {
    draw_header (menu->win, s, "%s", y, x, w, color, 0);
  }
}
Пример #3
0
/* render all windows */
static void
render_screens (void)
{
  GColors *color = get_color (COLOR_DEFAULT);
  int row, col, chg = 0;

  getmaxyx (stdscr, row, col);
  term_size (main_win);

  generate_time ();
  chg = logger->processed - logger->offset;

  draw_header (stdscr, "", "%s", row - 1, 0, col, color_default);

  wattron (stdscr, color->attr | COLOR_PAIR (color->pair->idx));
  mvaddstr (row - 1, 1, "[F1]Help [Enter] Exp. Panel");
  mvprintw (row - 1, 30, "%d - %s", chg, asctime (now_tm));
  mvaddstr (row - 1, col - 21, "[Q]uit GoAccess");
  mvprintw (row - 1, col - 5, "%s", GO_VERSION);
  wattroff (stdscr, color->attr | COLOR_PAIR (color->pair->idx));

  refresh ();

  /* call general stats header */
  display_general (header_win, conf.ifile, logger);
  wrefresh (header_win);

  /* display active label based on current module */
  update_active_module (header_win, gscroll.current);

  display_content (main_win, logger, dash, &gscroll);
}
Пример #4
0
/* render dashboard hits */
static void
render_visitors (GDashModule * data, GDashRender render, int *x)
{
  WINDOW *win = render.win;
  GModule module = data->module;
  const GDashStyle *style = module_style;

  char *visitors;
  int y = render.y, w = render.w, idx = render.idx, sel = render.sel;
  int len = data->visitors_len;

  if (data->module == HOSTS && data->data[idx].is_subitem)
    goto out;

  /* selected state */
  if (sel) {
    visitors = int_to_str (data->data[idx].metrics->visitors);
    draw_header (win, visitors, "%*s", y, *x, w, HIGHLIGHT, len);
    free (visitors);
  }
  /* regular state */
  else {
    wattron (win, A_BOLD | COLOR_PAIR (style[module].color_visitors));
    mvwprintw (win, y, *x, "%*d", len, data->data[idx].metrics->visitors);
    wattroff (win, A_BOLD | COLOR_PAIR (style[module].color_visitors));
  }
out:

  *x += len + DASH_SPACE;
}
Пример #5
0
/* render dashboard bandwidth */
static void
render_bandwidth (GDashModule * data, GDashRender render, int *x)
{
  WINDOW *win = render.win;
  GModule module = data->module;
  const GDashStyle *style = module_style;

  int y = render.y, w = render.w, idx = render.idx, sel = render.sel;
  char *bw = data->data[idx].metrics->bw.sbw;

  if (data->module == HOSTS && data->data[idx].is_subitem)
    goto out;
  if (style[module].color_bw == -1)
    return;

  /* selected state */
  if (sel) {
    draw_header (win, bw, "%11s", y, *x, w, HIGHLIGHT, 0);
  }
  /* regular state */
  else {
    wattron (win, A_BOLD | COLOR_PAIR (style[module].color_bw));
    mvwprintw (win, y, *x, "%11s", bw);
    wattroff (win, A_BOLD | COLOR_PAIR (style[module].color_bw));
  }
out:

  *x += DASH_BW_LEN + DASH_SPACE;
}
Пример #6
0
/* render dashboard request protocol */
static void
render_protocol (GDashModule * data, GDashRender render, int *x)
{
  WINDOW *win = render.win;
  GModule module = data->module;
  const GDashStyle *style = module_style;

  int y = render.y, w = render.w, idx = render.idx, sel = render.sel;
  char *protocol = data->data[idx].metrics->protocol;

  if (style[module].color_protocol == -1)
    return;

  if (protocol == NULL || *protocol == '\0')
    return;

  /* selected state */
  if (sel) {
    draw_header (win, protocol, "%s", y, *x, w, HIGHLIGHT, 0);
  }
  /* regular state */
  else {
    wattron (win, A_BOLD | COLOR_PAIR (style[module].color_protocol));
    mvwprintw (win, y, *x, "%s", protocol);
    wattroff (win, A_BOLD | COLOR_PAIR (style[module].color_protocol));
  }

  *x += REQ_PROTO_LEN - 1 + DASH_SPACE;
}
Пример #7
0
/* render all windows */
static void
render_screens (void)
{
  int row, col, chg = 0;

  getmaxyx (stdscr, row, col);
  term_size (main_win);

  generate_time ();
  chg = logger->process - logger->offset;

  draw_header (stdscr, "", "%s", row - 1, 0, col, 0, 0);
  wattron (stdscr, COLOR_PAIR (COL_WHITE));
  mvaddstr (row - 1, 1, "[F1]Help [O]pen detail view");
  mvprintw (row - 1, 30, "%d - %s", chg, asctime (now_tm));
  mvaddstr (row - 1, col - 21, "[Q]uit GoAccess");
  mvprintw (row - 1, col - 5, "%s", GO_VERSION);
  wattroff (stdscr, COLOR_PAIR (COL_WHITE));
  refresh ();

  /* call general stats header */
  display_general (header_win, conf.ifile, logger);
  wrefresh (header_win);

  /* display active label based on current module */
  update_active_module (header_win, gscroll.current);

  display_content (main_win, logger, dash, &gscroll);
}
Пример #8
0
static void
draw_page_text (GtkPrintOperation * op, GtkPrintContext * cnt, gint page, gpointer data)
{
  cairo_t *cr;
  PangoLayout *layout;
  gint i, line;

  cr = gtk_print_context_get_cairo_context (cnt);

  /* create header */
  if (options.print_data.headers)
    draw_header (cnt, page + 1, npages);

  /* add text */
  layout = gtk_print_context_create_pango_layout (cnt);
  pango_layout_set_font_description (layout, fdesc);

  cairo_move_to (cr, 0, HEADER_HEIGHT + HEADER_GAP);

  line = page * nlines;
  for (i = 0; i < nlines; i++)
    {
      if (text[line + i] == NULL)
        break;
      pango_layout_set_text (layout, text[line + i], -1);
      pango_cairo_show_layout (cr, layout);
      cairo_rel_move_to (cr, 0, FONTSIZE);
    }

  g_object_unref (layout);
}
Пример #9
0
// creates a new MandelPod window
void new_mandel_window(void)
{
	// get the graphics context
	mandel_gc = pz_get_gc(1);
		
	// create the main window
	mandel_wid = pz_new_window (0, 21,
				screen_info.cols, screen_info.rows - (HEADER_TOPLINE+1),
				draw_header, handle_event);
#ifdef MANDELPOD_STATUS
	// create the status window
	status_wid = pz_new_window (22, 4, 12, 12, draw_idle_status, handle_event);
#endif
	 // get screen info
	GrGetWindowInfo(mandel_wid, &wi);
	
	// select the event types
	GrSelectEvents (mandel_wid, GR_EVENT_MASK_EXPOSURE | GR_EVENT_MASK_KEY_DOWN | GR_EVENT_MASK_KEY_UP | GR_EVENT_MASK_TIMER);
		
	// display the window
	GrMapWindow (mandel_wid);
#ifdef MANDELPOD_STATUS
	GrMapWindow (status_wid);
#endif

    // create the timer for the busy status animation
    mandel_timer_id = GrCreateTimer (mandel_wid, 250);

	// start main app
	init_values();
	create_status();
	draw_header();
	calculate_mandel();
}
Пример #10
0
// Creates a new tunnel "app" window
void new_tunnel_window(void)
{
	
    tunnel_gc = pz_get_gc(1);       /* Get the graphics context */
	
    /* Open the window: */
    tunnel_wid = pz_new_window (0,
								   21,
								   screen_info.cols,
								   screen_info.rows - (HEADER_TOPLINE+1),
								   draw_header,
								   handle_event);
	
	GrGetWindowInfo(tunnel_wid, &wi); /* Get screen info */	
	
    /* Select the types of events you need for your window: */
    GrSelectEvents (tunnel_wid, GR_EVENT_MASK_TIMER|GR_EVENT_MASK_EXPOSURE|GR_EVENT_MASK_KEY_DOWN|GR_EVENT_MASK_KEY_UP);
	
	// set up pixmap 
	temp_pixmap = GrNewPixmap(screen_info.cols,
							  (screen_info.rows - (HEADER_TOPLINE + 1)),
							  NULL);
	
    /* Display the window: */
    GrMapWindow (tunnel_wid);
	draw_header();
	readHighScore();
	reset();
}
Пример #11
0
static void reset_board()
{
	int index;
	for(index = 0; index < 9; index++)
		board[index] = '-';
	
	difficulty = 6;
	gameRunning = 1;
	currSquare = 0;
	draw_header(); 
	
    /* Clear the window */
    GrClearWindow (tictactoe_wid, GR_FALSE);
	
	GrSetGCUseBackground(tictactoe_gc, GR_TRUE);
    GrSetGCBackground(tictactoe_gc, WHITE);
    GrSetGCForeground(tictactoe_gc, BLACK);
	
	GrLine(tictactoe_wid, tictactoe_gc, wi.width * .90, (wi.height / 2.) - (wi.height / 2. * .33), 
		   wi.width - wi.width * .90, (wi.height / 2.) - (wi.height / 2. * .33));
	GrLine(tictactoe_wid, tictactoe_gc, wi.width * .90, (wi.height / 2.) + (wi.height / 2. * .33), 
		   wi.width - wi.width * .90, (wi.height / 2.) + (wi.height / 2. * .33));
	
	GrLine(tictactoe_wid, tictactoe_gc, (wi.width / 2.) - (wi.width / 2. * .33), wi.height * .90, 
		   (wi.width / 2.) - (wi.width / 2. * .33), wi.height - wi.height * .90);
	GrLine(tictactoe_wid, tictactoe_gc, (wi.width / 2.) + (wi.width / 2. * .33), wi.height * .90, 
		   (wi.width / 2.) + (wi.width / 2. * .33), wi.height - wi.height * .90);
	currSquare = 0;
	drawXO(currSquare, GRAY, 'x');
}
Пример #12
0
/* Render the help dialog. */
static void
load_confdlg_error (WINDOW * parent_win, char **errors, int nerrors)
{
  int c, quit = 1, i = 0;
  int y, x, h = ERR_WIN_HEIGHT, w = ERR_WIN_WIDTH;
  WINDOW *win;
  GMenu *menu;

  getmaxyx (stdscr, y, x);

  win = newwin (h, w, (y - h) / 2, (x - w) / 2);
  keypad (win, TRUE);
  wborder (win, '|', '|', '-', '-', '+', '+', '+', '+');

  /* create a new instance of GMenu and make it selectable */
  menu =
    new_gmenu (win, ERR_MENU_HEIGHT, ERR_MENU_WIDTH, ERR_MENU_Y, ERR_MENU_X);
  menu->size = nerrors;

  /* add items to GMenu */
  menu->items = (GItem *) xcalloc (nerrors, sizeof (GItem));
  for (i = 0; i < nerrors; ++i) {
    menu->items[i].name = alloc_string (errors[i]);
    menu->items[i].checked = 0;
    free (errors[i]);
  }
  free (errors);
  post_gmenu (menu);

  draw_header (win, ERR_HEADER, " %s", 1, 1, w - 2, color_error);
  mvwprintw (win, 2, 2, "[UP/DOWN] to scroll - [q] to quit");

  wrefresh (win);
  while (quit) {
    c = wgetch (stdscr);
    switch (c) {
    case KEY_DOWN:
      gmenu_driver (menu, REQ_DOWN);
      break;
    case KEY_UP:
      gmenu_driver (menu, REQ_UP);
      break;
    case KEY_RESIZE:
    case 'q':
      quit = 0;
      break;
    }
    wrefresh (win);
  }
  /* clean stuff up */
  for (i = 0; i < nerrors; ++i)
    free (menu->items[i].name);
  free (menu->items);
  free (menu);

  touchwin (parent_win);
  close_win (win);
  wrefresh (parent_win);
}
Пример #13
0
/* Print out (terminal dashboard) the overall statistics header. */
static void
render_overall_header (WINDOW * win, GHolder * h)
{
  char *hd = get_overall_header (h);
  int col = getmaxx (stdscr);

  draw_header (win, hd, " %s", 0, 0, col, color_panel_header);
  free (hd);
}
Пример #14
0
static void
disabled_panel_msg (GModule module)
{
  const char *lbl = module_to_label (module);
  int row, col;

  getmaxyx (stdscr, row, col);
  draw_header (stdscr, lbl, "'%s' panel is disabled", row - 1, 0, col,
               WHITE_RED, 0);
}
Пример #15
0
/* render dashboard data */
static void
render_data (GDashModule * data, GDashRender render, int *x)
{
  WINDOW *win = render.win;
  GModule module = data->module;
  const GDashStyle *style = module_style;

  int y = render.y, w = render.w, idx = render.idx, sel = render.sel;

  char buf[DATE_LEN];
  char *value, *padded_data;

  value = substring (data->data[idx].metrics->data, 0, w - *x);
  if (module == VISITORS) {
    /* verify we have a valid date conversion */
    if (convert_date (buf, value, "%Y%m%d", "%d/%b/%Y", DATE_LEN) != 0) {
      LOG_DEBUG (("invalid date: %s", value));
      xstrncpy (buf, "---", 4);
    }
  }

  if (sel) {
    if (data->module == HOSTS && data->data[idx].is_subitem) {
      padded_data = left_pad_str (value, *x);
      draw_header (win, padded_data, "%s", y, 0, w, HIGHLIGHT, 0);
      free (padded_data);
    } else {
      draw_header (win, module == VISITORS ? buf : value, "%s", y, *x, w,
                   HIGHLIGHT, 0);
    }
  } else {
    wattron (win, COLOR_PAIR (style[module].color_data));
    mvwprintw (win, y, *x, "%s", module == VISITORS ? buf : value);
    wattroff (win, COLOR_PAIR (style[module].color_data));
  }

  *x += module == VISITORS ? DATE_LEN - 1 : data->data_len;
  *x += DASH_SPACE;
  free (value);
}
Пример #16
0
/* render processing spinner */
static void
ui_spinner (void *ptr_data)
{
  GSpinner *sp = (GSpinner *) ptr_data;
  GColors *color = NULL;

  static char const spin_chars[] = "/-\\|";
  char buf[SPIN_LBL];
  int i = 0;
  long long tdiff = 0, psec = 0;
  time_t begin;

  if (sp->curses)
    color = (*sp->color) ();

  time (&begin);
  while (1) {
    pthread_mutex_lock (&sp->mutex);
    if (sp->state == SPN_END)
      break;

    setlocale (LC_NUMERIC, "");
    if (conf.no_progress) {
      snprintf (buf, sizeof buf, SPIN_FMT, sp->label);
    } else {
      tdiff = (long long) (time (NULL) - begin);
      psec = tdiff >= 1 ? *(sp->processed) / tdiff : 0;
      snprintf (buf, sizeof buf, SPIN_FMTM, sp->label, *(sp->processed), psec);
    }
    setlocale (LC_NUMERIC, "POSIX");

    if (sp->curses) {
      /* CURSES */
      draw_header (sp->win, buf, " %s", sp->y, sp->x, sp->w, sp->color);
      /* caret */
      wattron (sp->win, COLOR_PAIR (color->pair->idx));
      mvwaddch (sp->win, sp->y, sp->spin_x, spin_chars[i++ & 3]);
      wattroff (sp->win, COLOR_PAIR (color->pair->idx));
      wrefresh (sp->win);
    } else if (!conf.no_progress) {
      /* STDOUT */
      fprintf (stderr, "%s\r", buf);
    }

    pthread_mutex_unlock (&sp->mutex);
    usleep (100000);
  }
  sp = NULL;
  free (sp);
}
Пример #17
0
static void
draw_formats (WINDOW * win, int w2)
{
  char *date_format = NULL, *log_format = NULL, *time_format = NULL;

  draw_header (win, "Log Format Configuration", " %s", 1, 1, w2,
               color_panel_header);
  mvwprintw (win, 2, 2, "[SPACE] to toggle - [ENTER] to proceed - [q]uit");

  /* set log format from config file if available */
  draw_header (win, "Log Format - [c] to add/edit format", " %s", 11, 1, w2,
               color_panel_header);
  if ((log_format = get_input_log_format ())) {
    mvwprintw (win, 12, 2, "%.*s", CONF_MENU_W, log_format);

    free (log_format);
  }

  /* set log format from config file if available */
  draw_header (win, "Date Format - [d] to add/edit format", " %s", 14, 1, w2,
               color_panel_header);
  if ((date_format = get_input_date_format ())) {
    mvwprintw (win, 15, 2, "%.*s", CONF_MENU_W, date_format);

    free (date_format);
  }

  /* set log format from config file if available */
  draw_header (win, "Time Format - [t] to add/edit format", " %s", 17, 1, w2,
               color_panel_header);
  if ((time_format = get_input_time_format ())) {
    mvwprintw (win, 18, 2, "%.*s", CONF_MENU_W, time_format);

    free (time_format);
  }
}
Пример #18
0
/* compile the regular expression and see if it's valid */
static int
regexp_init (regex_t * regex, const char *pattern)
{
  int y, x, rc;
  char buf[REGEX_ERROR];

  getmaxyx (stdscr, y, x);
  rc = regcomp (regex, pattern, REG_EXTENDED | (find_t.icase ? REG_ICASE : 0));
  /* something went wrong */
  if (rc != 0) {
    regerror (rc, regex, buf, sizeof (buf));
    draw_header (stdscr, buf, "%s", y - 1, 0, x, WHITE_RED, 0);
    refresh ();
    return 1;
  }
  return 0;
}
Пример #19
0
/* render module's total */
static void
render_total_label (WINDOW * win, GDashModule * data, int y, int color)
{
  char *s;
  int win_h, win_w, total, ht_size;

  total = data->holder_size;
  ht_size = data->ht_size;

  s = xmalloc (snprintf (NULL, 0, "Total: %d/%d", total, ht_size) + 1);
  getmaxyx (win, win_h, win_w);
  (void) win_h;

  sprintf (s, "Total: %d/%d", total, ht_size);
  draw_header (win, s, "%s", y, win_w - strlen (s) - 2, win_w, color, 0);
  free (s);
}
Пример #20
0
/* render processing spinner */
static void
ui_spinner (void *ptr_data)
{
  GSpinner *sp = (GSpinner *) ptr_data;

  static char const spin_chars[] = "/-\\|";
  char buf[SPIN_LBL];
  long long tdiff = 0, psec = 0;
  int i = 0;
  time_t begin;

  time (&begin);
  while (1) {
    pthread_mutex_lock (&sp->mutex);
    if (sp->state == SPN_END)
      break;

    tdiff = (long long) (time (NULL) - begin);
    psec = tdiff >= 1 ? *(sp->process) / tdiff : 0;
    snprintf (buf, sizeof buf, SPIN_FMT, sp->label, *(sp->process), psec);

    /* CURSES */
    if (sp->curses) {
      /* label + metrics */
      draw_header (sp->win, buf, " %s", sp->y, sp->x, sp->w, sp->color);

      /* caret */
      wattron (sp->win, COLOR_PAIR (sp->color));
      mvwaddch (sp->win, sp->y, sp->spin_x, spin_chars[i++ & 3]);
      wattroff (sp->win, COLOR_PAIR (sp->color));
      wrefresh (sp->win);
    }
    /* STDOUT */
    else {
      fprintf (stderr, "%s\r", buf);
    }

    pthread_mutex_unlock (&sp->mutex);
    usleep (100000);
  }
  sp = NULL;
  free (sp);
}
Пример #21
0
/* render dashboard percent */
static void
render_percent (GDashModule * data, GDashRender render, int *x)
{
  WINDOW *win = render.win;
  GModule module = data->module;
  const GDashStyle *style = module_style;

  char *percent;
  int y = render.y, w = render.w, idx = render.idx, sel = render.sel;
  int len = data->perc_len + 3;

  if (data->module == HOSTS && data->data[idx].is_subitem)
    goto out;
  if (style[module].color_percent == -1)
    return;

  /* selected state */
  if (sel) {
    percent = float_to_str (data->data[idx].metrics->percent);
    draw_header (win, percent, "%*s%%", y, *x, w, HIGHLIGHT, len);
    free (percent);
  }
  /* regular state */
  else {
    wattron (win, A_BOLD | COLOR_PAIR (style[module].color_percent));
    if (data->max_hits == data->data[idx].metrics->hits)
      wattron (win, A_BOLD | COLOR_PAIR (COL_YELLOW));
    if (style[module].color_percent == COL_BLACK)
      wattron (win, A_BOLD | COLOR_PAIR (style[module].color_percent));

    mvwprintw (win, y, *x, "%*.2f%%", len, data->data[idx].metrics->percent);

    if (style[module].color_percent == COL_BLACK)
      wattroff (win, A_BOLD | COLOR_PAIR (style[module].color_percent));
    if (data->max_hits == data->data[idx].metrics->hits)
      wattroff (win, A_BOLD | COLOR_PAIR (COL_YELLOW));
    wattroff (win, A_BOLD | COLOR_PAIR (style[module].color_percent));
  }
out:

  *x += len + 1 + DASH_SPACE;
}
Пример #22
0
/* render dashboard bars (graph) */
static void
render_bars (GDashModule * data, GDashRender render, int *x)
{
  WINDOW *win = render.win;
  GModule module = data->module;
  const GDashStyle *style = module_style;

  char *bar;
  int y = render.y, w = render.w, idx = render.idx, sel = render.sel;

  if (style[module].color_bars == -1)
    return;

  bar = get_bars (data->data[idx].metrics->hits, data->max_hits, *x);
  if (sel)
    draw_header (win, bar, "%s", y, *x, w, HIGHLIGHT, 0);
  else
    mvwprintw (win, y, *x, "%s", bar);
  free (bar);
}
Пример #23
0
static void
draw_page_image (GtkPrintOperation * op, GtkPrintContext * cnt, gint page, gpointer data)
{
  cairo_t *cr;
  GdkPixbuf *pb, *spb;
  guint iw, ih;
  gdouble pw, ph;
  gdouble factor;

  cr = gtk_print_context_get_cairo_context (cnt);

  pw = gtk_print_context_get_width (cnt);
  ph = gtk_print_context_get_height (cnt);
  if (options.print_data.headers)
    ph -= HEADER_HEIGHT + HEADER_GAP;

  /* create header */
  if (options.print_data.headers)
    draw_header (cnt, 1, 1);

  /* scale image to page size */
  pb = gdk_pixbuf_new_from_file (options.common_data.uri, NULL);
  iw = gdk_pixbuf_get_width (pb);
  ih = gdk_pixbuf_get_height (pb);

  if (pw < iw || ph < ih)
    {
      factor = MIN (pw / iw, ph / ih);
      factor = (factor > 1.0) ? 1.0 : factor;
      spb = gdk_pixbuf_scale_simple (pb, iw * factor, ih * factor, GDK_INTERP_HYPER);
    }
  else
    spb = g_object_ref (pb);
  g_object_unref (pb);

  /* add image to surface */
  gdk_cairo_set_source_pixbuf (cr, spb, 0.0, HEADER_HEIGHT + HEADER_GAP);
  cairo_paint (cr);
  g_object_unref (spb);
}
Пример #24
0
void
display_general (WINDOW * win, char *ifile, GLog * logger)
{
  GColors *(*colorlbl) (void) = color_overall_lbls;
  GColors *(*colorpth) (void) = color_overall_path;
  GColors *(*colorval) (void) = color_overall_vals;

  int col = getmaxx (stdscr);
  size_t n, i;

  /* *INDENT-OFF* */
  Field fields[] = {
    {T_REQUESTS   , get_str_processed_reqs (logger)  , colorlbl , colorval , 0},
    {T_UNIQUE_VIS , get_str_visitors ()              , colorlbl , colorval , 0},
    {T_UNIQUE_FIL , get_str_reqs ()                  , colorlbl , colorval , 0},
    {T_REFERRER   , get_str_ref_reqs ()              , colorlbl , colorval , 0},
    {T_VALID      , get_str_valid_reqs (logger)      , colorlbl , colorval , 0},
    {T_GEN_TIME   , get_str_proctime ()              , colorlbl , colorval , 0},
    {T_STATIC_FIL , get_str_static_reqs ()           , colorlbl , colorval , 0},
    {T_LOG        , get_str_filesize (logger, ifile) , colorlbl , colorval , 0},
    {T_FAILED     , get_str_failed_reqs (logger)     , colorlbl , colorval , 0},
    {T_EXCLUDE_IP , get_str_excluded_ips (logger)    , colorlbl , colorval , 0},
    {T_UNIQUE404  , get_str_notfound_reqs ()         , colorlbl , colorval , 0},
    {T_BW         , get_str_bandwidth (logger)       , colorlbl , colorval , 0},
    {T_LOG_PATH   , get_str_logfile (logger, ifile)  , colorlbl , colorpth , 1}
  };
  /* *INDENT-ON* */

  werase (win);
  draw_header (win, T_DASH " - " T_HEAD, " %s", 0, 0, col, color_panel_header);

  n = ARRAY_SIZE (fields);
  render_overall_statistics (win, fields, n);

  for (i = 0; i < n; i++) {
    free (fields[i].value);
  }
}
Пример #25
0
static void
render_header (WINDOW * win, GDashModule * data, GModule cur_module, int *y)
{
  char ind;
  char *hd;
  int k, w, h, color;

  getmaxyx (win, h, w);
  (void) h;

  k = data->module + 1;
  ind = cur_module == data->module ? '>' : ' ';
  color = cur_module == data->module &&
    conf.hl_header ? YELLOW_BLACK : HIGHLIGHT;
  hd = xmalloc (snprintf (NULL, 0, "%c %d - %s", ind, k, data->head) + 1);
  sprintf (hd, "%c %d - %s", ind, k, data->head);

  draw_header (win, hd, " %s", (*y), 0, w, color, 0);
  free (hd);

  render_total_label (win, data, (*y), color);
  data->pos_y = (*y);
  (*y)++;
}
Пример #26
0
/* render config log date/format dialog */
int
verify_format (GLog * logger, GSpinner * spinner)
{
  GMenu *menu;
  WINDOW *win;

  char *cstm_log, *cstm_date;
  int c, quit = 1;
  int invalid = 1;
  int y, x, h = CONF_WIN_H, w = CONF_WIN_W;
  int w2 = w - 2;
  size_t i, n, sel;

  /* conf dialog menu options */
  const char *choices[] = {
    "Common Log Format (CLF)",
    "Common Log Format (CLF) with Virtual Host",
    "NCSA Combined Log Format",
    "NCSA Combined Log Format with Virtual Host",
    "W3C",
    "CloudFront (Download Distribution)"
  };
  n = ARRAY_SIZE (choices);
  getmaxyx (stdscr, y, x);

  win = newwin (h, w, (y - h) / 2, (x - w) / 2);
  keypad (win, TRUE);
  wborder (win, '|', '|', '-', '-', '+', '+', '+', '+');

  /* create a new instance of GMenu and make it selectable */
  menu = new_gmenu (win, CONF_MENU_H, CONF_MENU_W, CONF_MENU_Y, CONF_MENU_X);
  menu->size = n;
  menu->selectable = 1;

  /* add items to GMenu */
  menu->items = (GItem *) xcalloc (n, sizeof (GItem));
  for (i = 0; i < n; ++i) {
    menu->items[i].name = alloc_string (choices[i]);
    sel = get_selected_format_idx ();
    menu->items[i].checked = sel == i ? 1 : 0;
  }
  post_gmenu (menu);

  draw_header (win, "Log Format Configuration", " %s", 1, 1, w2, 1, 0);
  mvwprintw (win, 2, 2, "[SPACE] to toggle - [ENTER] to proceed");

  /* set log format from goaccessrc if available */
  draw_header (win, "Log Format - [c] to add/edit format", " %s", 11, 1, w2, 1,
               0);
  if (conf.log_format) {
    log_format = escape_str (conf.log_format);
    mvwprintw (win, 12, 2, "%.*s", CONF_MENU_W, log_format);
    if (conf.log_format)
      free (conf.log_format);
  }

  /* set date format from goaccessrc if available */
  draw_header (win, "Date Format - [d] to add/edit format", " %s", 14, 1, w2, 1,
               0);
  if (conf.date_format) {
    date_format = escape_str (conf.date_format);
    mvwprintw (win, 15, 2, "%.*s", CONF_MENU_W, date_format);
    if (conf.date_format)
      free (conf.date_format);
  }

  wrefresh (win);
  while (quit) {
    c = wgetch (stdscr);
    switch (c) {
     case KEY_DOWN:
       gmenu_driver (menu, REQ_DOWN);
       draw_header (win, "", "%s", 3, 2, CONF_MENU_W, 0, 0);
       break;
     case KEY_UP:
       gmenu_driver (menu, REQ_UP);
       draw_header (win, "", "%s", 3, 2, CONF_MENU_W, 0, 0);
       break;
     case 32:  /* space */
       gmenu_driver (menu, REQ_SEL);

       if (date_format)
         free (date_format);
       if (log_format)
         free (log_format);

       for (i = 0; i < n; ++i) {
         if (menu->items[i].checked != 1)
           continue;

         date_format = get_selected_date_str (i);
         log_format = get_selected_format_str (i);
         draw_header (win, date_format, " %s", 15, 1, CONF_MENU_W, 0, 0);
         draw_header (win, log_format, " %s", 12, 1, CONF_MENU_W, 0, 0);
         break;
       }
       break;
     case 99:  /* c */
       /* clear top status bar */
       draw_header (win, "", "%s", 3, 2, CONF_MENU_W, 0, 0);
       wmove (win, 12, 2);

       /* get input string */
       cstm_log = input_string (win, 12, 2, 70, log_format, 0, 0);
       if (cstm_log != NULL && *cstm_log != '\0') {
         if (log_format)
           free (log_format);

         log_format = alloc_string (cstm_log);
         free (cstm_log);
       }
       /* did not set an input string */
       else {
         if (cstm_log)
           free (cstm_log);
         if (log_format) {
           free (log_format);
           log_format = NULL;
         }
       }
       break;
     case 100: /* d */
       /* clear top status bar */
       draw_header (win, "", "%s", 3, 2, CONF_MENU_W, 0, 0);
       wmove (win, 15, 0);

       /* get input string */
       cstm_date = input_string (win, 15, 2, 14, date_format, 0, 0);
       if (cstm_date != NULL && *cstm_date != '\0') {
         if (date_format)
           free (date_format);

         date_format = alloc_string (cstm_date);
         free (cstm_date);
       }
       /* did not set an input string */
       else {
         if (cstm_date)
           free (cstm_date);
         if (date_format) {
           free (date_format);
           date_format = NULL;
         }
       }
       break;
     case 274: /* F10 */
     case 0x0a:
     case 0x0d:
     case KEY_ENTER:
       /* display status bar error messages */
       if (date_format == NULL)
         draw_header (win, "Select a date format.", "%s", 3, 2, CONF_MENU_W,
                      WHITE_RED, 0);
       if (log_format == NULL)
         draw_header (win, "Select a log format.", "%s", 3, 2, CONF_MENU_W,
                      WHITE_RED, 0);

       if (date_format && log_format) {
         conf.date_format = unescape_str (date_format);
         conf.log_format = unescape_str (log_format);

         /* test log against selected settings */
         if (test_format (logger)) {
           invalid = 1;
           draw_header (win, "No valid hits.", "%s", 3, 2, CONF_MENU_W,
                        WHITE_RED, 0);

           free (conf.log_format);
           free (conf.date_format);
         }
         /* valid data, reset logger & start parsing */
         else {
           reset_struct (logger);
           /* start spinner thread */
           spinner->win = win;
           spinner->y = 3;
           spinner->x = 2;
           spinner->spin_x = CONF_MENU_W;
           spinner->w = CONF_MENU_W;
           spinner->color = BLACK_CYAN;
           ui_spinner_create (spinner);

           invalid = 0;
           quit = 0;
         }
       }
       break;
     case KEY_RESIZE:
     case 'q':
       quit = 0;
       break;
    }
    pthread_mutex_lock (&spinner->mutex);
    wrefresh (win);
    pthread_mutex_unlock (&spinner->mutex);
  }
  /* clean stuff up */
  for (i = 0; i < n; ++i)
    free (menu->items[i].name);
  free (menu->items);
  free (menu);

  return invalid ? 1 : 0;
}
Пример #27
0
/* render a list of agents if available */
void
load_agent_list (WINDOW * main_win, char *addr)
{
  char buf[256];
  char *ptr_value;
  GAgents *agents = NULL;
  GMenu *menu;
  int c, quit = 1, delims = 0;
  int i, n = 0, alloc = 0;
  int y, x, list_h, list_w, menu_w, menu_h;
  void *value_ptr = NULL;
  WINDOW *win;

  if (!conf.list_agents)
    return;

  getmaxyx (stdscr, y, x);
  list_h = y / 2;       /* list window - height */
  list_w = x - 4;       /* list window - width */
  menu_h = list_h - AGENTS_MENU_Y - 1;  /* menu window - height */
  menu_w = list_w - AGENTS_MENU_X - AGENTS_MENU_X;      /* menu window - width */

#ifdef HAVE_LIBTOKYOCABINET
  value_ptr = tc_db_get_str (ht_hosts_agents, addr);
#else
  value_ptr = g_hash_table_lookup (ht_hosts_agents, addr);
#endif

  if (value_ptr != NULL) {
    ptr_value = (char *) value_ptr;
    delims = count_matches (ptr_value, '|');

    n = ((strlen (ptr_value) + menu_w - 1) / menu_w) + delims + 1;
    agents = new_gagents (n);
    alloc = split_agent_str (ptr_value, agents, menu_w);
#ifdef HAVE_LIBTOKYOCABINET
    free (value_ptr);
#endif
  }

  win = newwin (list_h, list_w, (y - list_h) / 2, (x - list_w) / 2);
  keypad (win, TRUE);
  wborder (win, '|', '|', '-', '-', '+', '+', '+', '+');

  /* create a new instance of GMenu and make it selectable */
  menu = new_gmenu (win, menu_h, menu_w, AGENTS_MENU_Y, AGENTS_MENU_X);

  /* add items to GMenu */
  menu->items = (GItem *) xcalloc (alloc, sizeof (GItem));
  for (i = 0; i < alloc; ++i) {
    menu->items[i].name = alloc_string (agents[i].agents);
    menu->items[i].checked = 0;
    menu->size++;
  }
  post_gmenu (menu);

  snprintf (buf, sizeof buf, "User Agents for %s", addr);
  draw_header (win, buf, " %s", 1, 1, list_w - 2, 1, 0);
  mvwprintw (win, 2, 2, "[UP/DOWN] to scroll - [q] to close window");

  wrefresh (win);
  while (quit) {
    c = wgetch (stdscr);
    switch (c) {
     case KEY_DOWN:
       gmenu_driver (menu, REQ_DOWN);
       draw_header (win, "", "%s", 3, 2, CONF_MENU_W, 0, 0);
       break;
     case KEY_UP:
       gmenu_driver (menu, REQ_UP);
       draw_header (win, "", "%s", 3, 2, CONF_MENU_W, 0, 0);
       break;
     case KEY_RESIZE:
     case 'q':
       quit = 0;
       break;
    }
    wrefresh (win);
  }
  /* clean stuff up */
  for (i = 0; i < alloc; ++i)
    free (menu->items[i].name);
  free (menu->items);
  free (menu);

  for (i = 0; i < alloc; ++i)
    free (agents[i].agents);
  if (agents)
    free (agents);

  touchwin (main_win);
  close_win (win);
  wrefresh (main_win);
}
Пример #28
0
/* implement basic frame work to build a field input */
char *
input_string (WINDOW * win, int pos_y, int pos_x, size_t max_width,
              const char *str, int enable_case, int *toggle_case)
{
  char *s = xmalloc (max_width + 1), *tmp;
  size_t pos = 0, x = 0, quit = 1, c;

  /* window dimensions */
  size_t size_x = 0, size_y = 0, i;
  getmaxyx (win, size_y, size_x);
  size_x -= 4;

  /* are we setting a default string */
  if (str) {
    size_t len = MIN (max_width, strlen (str));
    memcpy (s, str, len);
    s[len] = '\0';

    x = pos = 0;
    /* is the default str length greater than input field? */
    if (strlen (s) > size_x) {
      tmp = xstrdup (&s[0]);
      tmp[size_x] = '\0';
      mvwprintw (win, pos_y, pos_x, "%s", tmp);
      free (tmp);
    } else
      mvwprintw (win, pos_y, pos_x, "%s", s);
  } else
    s[0] = '\0';

  if (enable_case)
    draw_header (win, "[x] case sensitive", " %s", size_y - 2, 1, size_x - 2, 2,
                 0);

  wmove (win, pos_y, pos_x + x);
  wrefresh (win);

  curs_set (1);
  while (quit) {
    c = wgetch (stdscr);
    switch (c) {
     case 1:   /* ^a   */
     case 262: /* HOME */
       pos = x = 0;
       break;
     case 5:
     case 360: /* END of line */
       if (strlen (s) > size_x) {
         x = size_x;
         pos = strlen (s) - size_x;
       } else {
         pos = 0;
         x = strlen (s);
       }
       break;
     case 7:   /* ^g  */
     case 27:  /* ESC */
       pos = x = 0;
       if (str && *str == '\0')
         s[0] = '\0';
       quit = 0;
       break;
     case 9:   /* TAB   */
       if (!enable_case)
         break;
       *toggle_case = *toggle_case == 0 ? 1 : 0;
       if (*toggle_case)
         draw_header (win, "[ ] case sensitive", " %s", size_y - 2, 1,
                      size_x - 2, 2, 0);
       else if (!*toggle_case)
         draw_header (win, "[x] case sensitive", " %s", size_y - 2, 1,
                      size_x - 2, 2, 0);
       break;
     case 21:  /* ^u */
       s[0] = '\0';
       pos = x = 0;
       break;
     case 8:   /* xterm-256color */
     case 127:
     case KEY_BACKSPACE:
       if (pos + x > 0) {
         memmove (&s[(pos + x) - 1], &s[pos + x], (max_width - (pos + x)) + 1);
         if (pos <= 0)
           x--;
         else
           pos--;
       }
       break;
     case KEY_LEFT:
       if (x > 0)
         x--;
       else if (pos > 0)
         pos--;
       break;
     case KEY_RIGHT:
       if ((x + pos) < strlen (s)) {
         if (x < size_x)
           x++;
         else
           pos++;
       }
       break;
     case 0x0a:
     case 0x0d:
     case KEY_ENTER:
       quit = 0;
       break;
     default:
       if (strlen (s) == max_width)
         break;
       if (!isprint (c))
         break;

       if (strlen (s) == pos) {
         s[pos + x] = c;
         s[pos + x + 1] = '\0';
         waddch (win, c);
       } else {
         memmove (&s[pos + x + 1], &s[pos + x], strlen (&s[pos + x]) + 1);
         s[pos + x] = c;
       }
       if ((x + pos) < max_width) {
         if (x < size_x)
           x++;
         else
           pos++;
       }
    }
    tmp = xstrdup (&s[pos > 0 ? pos : 0]);
    tmp[MIN (strlen (tmp), size_x)] = '\0';
    for (i = strlen (tmp); i < size_x; i++)
      mvwprintw (win, pos_y, pos_x + i, "%s", " ");
    mvwprintw (win, pos_y, pos_x, "%s", tmp);
    free (tmp);

    wmove (win, pos_y, pos_x + x);
    wrefresh (win);
  }
  curs_set (0);
  return s;
}
Пример #29
0
/* render general statistics */
void
display_general (WINDOW * win, char *ifile, GLog * logger)
{
  char *bw, *size, *log_file;
  char *failed, *not_found, *process, *ref, *req;
  char *static_files, *now, *visitors, *exclude_ip;

  int x_field = 2, x_value = 0;
  size_t n, i, j, max_field = 0, max_value = 0, mod_val, y;

  typedef struct Field_
  {
    const char *field;
    char *value;                /* char due to log, bw, log_file */
    int color;
  } Field;

  Field fields[] = {
    {T_REQUESTS, NULL, COL_CYAN},
    {T_UNIQUE_VIS, NULL, COL_CYAN},
    {T_REFERRER, NULL, COL_CYAN},
    {T_LOG, NULL, COL_CYAN},
    {T_F_REQUESTS, NULL, COL_CYAN},
    {T_UNIQUE_FIL, NULL, COL_CYAN},
    {T_UNIQUE404, NULL, COL_CYAN},
    {T_BW, NULL, COL_CYAN},
    {T_GEN_TIME, NULL, COL_CYAN},
    {T_EXCLUDE_IP, NULL, COL_CYAN},
    {T_STATIC_FIL, NULL, COL_CYAN},
    {T_LOG_PATH, NULL, COL_YELLOW}
  };

  werase (win);
  draw_header (win, T_HEAD, " %s", 0, 0, getmaxx (stdscr), 1, 0);

  if (!logger->piping && ifile != NULL) {
    size = filesize_str (file_size (ifile));
    log_file = alloc_string (ifile);
  } else {
    size = alloc_string ("N/A");
    log_file = alloc_string ("STDIN");
  }
  bw = filesize_str ((float) logger->resp_size);

  /* *INDENT-OFF* */
  failed       = int_to_str (logger->invalid);
  not_found    = int_to_str (get_ht_size (ht_not_found_requests));
  process      = int_to_str (logger->process);
  ref          = int_to_str (get_ht_size (ht_referrers));
  req          = int_to_str (get_ht_size(ht_requests));
  static_files = int_to_str (get_ht_size(ht_requests_static));
  now          = int_to_str (((long long) end_proc - start_proc));
  visitors     = int_to_str (get_ht_size(ht_unique_visitors));
  exclude_ip    = int_to_str (logger->exclude_ip);

  fields[0].value = process;
  fields[1].value = visitors;
  fields[2].value = ref;
  fields[3].value = size;
  fields[4].value = failed;
  fields[5].value = req;
  fields[6].value = not_found;
  fields[7].value = bw;
  fields[8].value = now;
  fields[9].value = exclude_ip;
  fields[10].value = static_files;
  fields[11].value = log_file;

  n = ARRAY_SIZE (fields);

  /* *INDENT-ON* */
  for (i = 0, y = 2; i < n; i++) {
    mod_val = i % 4;
    if (i > 0 && mod_val == 0) {
      max_field = 0;
      max_value = 0;
      x_field = 2;
      x_value = 2;
      y++;
    }

    x_field += max_field;
    mvwprintw (win, y, x_field, "%s", fields[i].field);

    max_field = 0;
    for (j = 0; j < n; j++) {
      size_t len = strlen (fields[j].field);
      if (j % 4 == mod_val && len > max_field)
        max_field = len;
    }

    max_value = 0;
    for (j = 0; j < n; j++) {
      size_t len = strlen (fields[j].value);
      if (j % 4 == mod_val && len > max_value)
        max_value = len;
    }
    x_value = max_field + x_field + 1;
    max_field += max_value + 2;

    wattron (win, A_BOLD | COLOR_PAIR (fields[i].color));
    mvwprintw (win, y, x_value, "%s", fields[i].value);
    wattroff (win, A_BOLD | COLOR_PAIR (fields[i].color));
  }
  for (i = 0; i < n; i++) {
    free (fields[i].value);
  }
}
Пример #30
0
/* render sort dialog */
void
load_sort_win (WINDOW * main_win, GModule module, GSort * sort)
{
  GMenu *menu;
  int c, quit = 1;
  int i = 0, k, n = 0;
  int opts[SORT_MAX_OPTS];
  int y, x, h = SORT_WIN_H, w = SORT_WIN_W;
  int w2 = w - 2;
  WINDOW *win;

  getmaxyx (stdscr, y, x);

  /* determine amount of sort choices */
  for (i = 0, k = 0; NULL != sort_choices[module][i]; i++) {
    const char *name = sort_choices[module][i];
    if (strcmp ("Time Served", name) == 0 && !conf.serve_usecs)
      continue;
    else if (strcmp ("Bandwidth", name) == 0 && !conf.bandwidth)
      continue;
    else if (strcmp ("Protocol", name) == 0 && !conf.append_protocol)
      continue;
    else if (strcmp ("Method", name) == 0 && !conf.append_method)
      continue;
    opts[k++] = i;
    n++;
  }

  win = newwin (h, w, (y - h) / 2, (x - w) / 2);
  keypad (win, TRUE);
  wborder (win, '|', '|', '-', '-', '+', '+', '+', '+');

  /* create a new instance of GMenu and make it selectable */
  menu = new_gmenu (win, SORT_MENU_H, SORT_MENU_W, SORT_MENU_Y, SORT_MENU_X);
  menu->size = n;
  menu->selectable = 1;

  /* add items to GMenu */
  menu->items = (GItem *) xcalloc (n, sizeof (GItem));

  /* set checked option and set index */
  for (i = 0; i < n; ++i) {
    menu->items[i].name = alloc_string (sort_choices[module][opts[i]]);
    if (sort->field == SORT_BY_HITS &&
        strcmp ("Hits", menu->items[i].name) == 0) {
      menu->items[i].checked = 1;
      menu->idx = i;
    } else if (sort->field == SORT_BY_DATA &&
               strcmp ("Data", menu->items[i].name) == 0) {
      menu->items[i].checked = 1;
      menu->idx = i;
    } else if (sort->field == SORT_BY_BW &&
               strcmp ("Bandwidth", menu->items[i].name) == 0) {
      menu->items[i].checked = 1;
      menu->idx = i;
    } else if (sort->field == SORT_BY_USEC &&
               strcmp ("Time Served", menu->items[i].name) == 0) {
      menu->items[i].checked = 1;
      menu->idx = i;
    } else if (sort->field == SORT_BY_PROT &&
               strcmp ("Protocol", menu->items[i].name) == 0) {
      menu->items[i].checked = 1;
      menu->idx = i;
    } else if (sort->field == SORT_BY_MTHD &&
               strcmp ("Method", menu->items[i].name) == 0) {
      menu->items[i].checked = 1;
      menu->idx = i;
    }
  }
  post_gmenu (menu);

  draw_header (win, "Sort active module by", " %s", 1, 1, w2, 1, 0);
  mvwprintw (win, 2, 2, "[ENTER] to select field - [TAB] sort");
  if (sort->sort == SORT_ASC)
    draw_header (win, "[x] ASC [ ] DESC", " %s", SORT_WIN_H - 2, 1,
                 SORT_WIN_W - 2, 2, 0);
  else
    draw_header (win, "[ ] ASC [x] DESC", " %s", SORT_WIN_H - 2, 1,
                 SORT_WIN_W - 2, 2, 0);

  wrefresh (win);
  while (quit) {
    c = wgetch (stdscr);
    switch (c) {
     case KEY_DOWN:
       gmenu_driver (menu, REQ_DOWN);
       draw_header (win, "", "%s", 3, 2, SORT_MENU_W, 0, 0);
       break;
     case KEY_UP:
       gmenu_driver (menu, REQ_UP);
       draw_header (win, "", "%s", 3, 2, SORT_MENU_W, 0, 0);
       break;
     case 9:   /* TAB */
       /* ascending */
       if (sort->sort == SORT_ASC) {
         sort->sort = SORT_DESC;
         draw_header (win, "[ ] ASC [x] DESC", " %s", SORT_WIN_H - 2, 1,
                      SORT_WIN_W - 2, 2, 0);
       }
       /* descending */
       else {
         sort->sort = SORT_ASC;
         draw_header (win, "[x] ASC [ ] DESC", " %s", SORT_WIN_H - 2, 1,
                      SORT_WIN_W - 2, 2, 0);
       }
       break;
     case 32:
     case 0x0a:
     case 0x0d:
     case KEY_ENTER:
       gmenu_driver (menu, REQ_SEL);
       for (i = 0; i < n; ++i) {
         if (menu->items[i].checked != 1)
           continue;
         if (strcmp ("Hits", menu->items[i].name) == 0)
           sort->field = SORT_BY_HITS;
         else if (strcmp ("Data", menu->items[i].name) == 0)
           sort->field = SORT_BY_DATA;
         else if (strcmp ("Bandwidth", menu->items[i].name) == 0)
           sort->field = SORT_BY_BW;
         else if (strcmp ("Time Served", menu->items[i].name) == 0)
           sort->field = SORT_BY_USEC;
         else if (strcmp ("Protocol", menu->items[i].name) == 0)
           sort->field = SORT_BY_PROT;
         else if (strcmp ("Method", menu->items[i].name) == 0)
           sort->field = SORT_BY_MTHD;
         quit = 0;
         break;
       }
       break;
     case KEY_RESIZE:
     case 'q':
       quit = 0;
       break;
    }
    wrefresh (win);
  }

  /* clean stuff up */
  for (i = 0; i < n; ++i)
    free (menu->items[i].name);
  free (menu->items);
  free (menu);

  touchwin (main_win);
  close_win (win);
  wrefresh (main_win);
}