⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sscr.c

📁 P2P NAP的C实现 P2P在网络应用中越来越流行
💻 C
字号:
/* Copyright (c) 2000  Kevin Sullivan <nite@gis.net> * * Please refer to the COPYRIGHT file for more information. */#include <stdio.h>#include <string.h>#include <ncurses.h>#include <stdlib.h>#include <ctype.h>#include <sys/time.h>#include "defines.h"#include "colors.h"#include "codes.h"#include "scheck.h"#include "nap.h"#include "winio.h"#include "sscr.h"#include "lists.h"#include "alias.h"#include "status_line.h"#ifdef MEMWATCH  #include "memwatch.h"#endifextern char *conns[];extern ssearch_t *search; /* search result list */extern int srch;          /* 1 while search in progress */extern info_t info;/* Command-line-related variables from winio.c */extern cmds_t *ccmd;extern char    cbuf[];extern int     curr;extern int     curx;/* curses windows and global state for search screen */WINDOW *swin;int cy;             /* item number aligned with first line on screen */int num;            /* item that the cursor is on */int lk;             /* 0 if status line should be set to filename */int max;            /* number of search results */int showconn;       /* show connection speed? */int showping;       /* show ping? (Note this will only be shown, by                       default, if pings are actually available) */int showuser;       /* show user nickname? */int showbrate;      /* show bitrate? */int showlength;     /* show length? */int showfreq;       /* show frequency? */int showsize;       /* show size? */char lastsort;      /* indicates what the most recent sort key was */int usercols;       /* width of longest user name *//* initialize result screen state. Note: this only needs to be called   when a new list of search results was generated, not each time we   switch to the result screen. This way, the state will be preserved   while switching back and forth between screens */void resetsscr(void){  ssearch_t *cur;  char *defaults;  cy = 1;  /* note search items are numbered starting from 1 */  num = 1;  lastsort = 0;    /* determine number of items in search list, and maximum size of     username */    max = 0;  usercols = 4;  list_forall(cur, search) {    max++;    if (strlen(cur->nick) > usercols)      usercols = strlen(cur->nick);  }  showconn = 0;  showping = 0;  showuser = 0;  showbrate = 0;  showlength = 0;  showfreq = 0;  showsize = 0;  defaults = getval("sdefaults");  if (!defaults)    defaults = "blsp";  while (*defaults) {    shandlechar(*defaults);    defaults++;  }  /* turn off display of connection speed and/or pings if the     information is not available */  showconn = (showconn && search && search->conn != -1) ? 1 : 0;  showping = (showping && search && search->ping > -2) ? 1 : 0;  /* reset screen and cursor to first item (after possible sorting!) */  cy = 1;   num = 1;}/* turn on result screen */void searchscr(void){  sock_t *sk;  sk = findsock("input");  if (sk) {    sk->func = sinput;  }  swin = newwin("sscr", LINES, 0, 0, 0);  wbkgdset(swin, COLOR_PAIR(CPW));  keypad(swin, TRUE);  werase(swin);  sl_set("Use F1 or 'q' to return to the main screen. 'h' for help.");  lk = 1;  plist();}/* turn off result screen */void endsearchscr(){  delwin(swin);}/* print result screen */void plist(){  int j, ln=0, min, sec, col, titlecols;  ssearch_t *cur;  float mb;  char *t=NULL;    if (screen != RESULT_SCREEN)    return;    if (srch)  {    werase(swin);    mvwprintw(swin, LINES/2, (COLS-29)/2, "Waiting for search results...");    sl_draw();    wrefresh(swin);    return;  }    if (!search)  {    werase(swin);    mvwprintw(swin, LINES/2, (COLS-25)/2, "No search results to list");    sl_draw();    wrefresh(swin);    return;  }    if (num > max)    num = max;  if (cy > max)    cy = max-(LINES-3)+1;  if (cy < 1)    cy = 1;  if (num >= (LINES-3)+cy)      /* screen follows cursor */  {    cy = num-(LINES-3)+1;  }  if (num < cy)  {    cy = num;  }    /* decide how many columns to use for filenames (=titlecols) */  titlecols = COLS - 1;  titlecols -= 8*showbrate;  titlecols -= 9*showlength;  titlecols -= (3+usercols)*showuser;  titlecols -= 12*showconn;  titlecols -= 7*showping;  titlecols -= 8*showfreq;  switch (showsize) {  case 1:    titlecols -= 9;    break;  case 2:    titlecols -= 12;    break;  case 0: default:    break;  }  if (titlecols < 14)    titlecols = 14;    werase(swin);    msprintf(&t, "Filename (total = %d)", max);  if (strlen(t) > titlecols)    t[titlecols]=0;  mvwprintw(swin, 0, 0, "%s", t);  wmove(swin, 1, 0);  whline(swin, ACS_HLINE, COLS);  col = titlecols;  if (showbrate) {    mvwprintw(swin, 0, col+3, "BRate");    wmove(swin, 0, col+1);    wvline(swin, ACS_VLINE, LINES-1);    col += 8;  }  if (showlength) {    mvwprintw(swin, 0, col+3, "Length");    wmove(swin, 0, col+1);    wvline(swin, ACS_VLINE, LINES-1);    col += 9;  }  switch (showsize) {  case 1:    mvwprintw(swin, 0, col+3, "MBytes");    wmove(swin, 0, col+1);    wvline(swin, ACS_VLINE, LINES-1);    col += 9;    break;  case 2:    mvwprintw(swin, 0, col+3, "  Bytes");    wmove(swin, 0, col+1);    wvline(swin, ACS_VLINE, LINES-1);    col += 12;    break;  case 0: default:    break;  }  if (showfreq) {    mvwprintw(swin, 0, col+3, "Freq");    wmove(swin, 0, col+1);    wvline(swin, ACS_VLINE, LINES-1);    col += 8;  }  if (showuser) {    mvwprintw(swin, 0, col+3, "User");    wmove(swin, 0, col+1);    wvline(swin, ACS_VLINE, LINES-1);    col += 3+usercols;  }  if (showconn) {    mvwprintw(swin, 0, col+3, "Speed");    wmove(swin, 0, col+1);    wvline(swin, ACS_VLINE, LINES-1);    col += 12;  }  if (showping) {    mvwprintw(swin, 0, col+3, "Ping");    wmove(swin, 0, col+1);    wvline(swin, ACS_VLINE, LINES-1);    col += 7;  }  /* find cy'th element of the list (remember list macros count from     0, but cy counts from 1 */  list_nth(cur, search, cy-1);  for (j=cy, ln=0; cur && ln < LINES-3; j++, ln++, cur=cur->next)  {    if (num == j)    {      if (!lk) {	sl_set(quote(cur->rfn));      }      wattron(swin, COLOR_PAIR(1)|A_BOLD);      wmove(swin, ln+2, 0);      whline(swin, ' ', COLS);    }        msprintf(&t, "%i) %s", j, cur->song);    if (strlen(t) > titlecols)      t[titlecols]=0;    mvwprintw(swin, ln+2, 0, "%s", t);    col = titlecols;        if (showbrate) {      mvwprintw(swin, ln+2, col+3, "%4i", cur->brate);      if (num==j) {	wmove(swin, ln+2, col+1);	wvline(swin, ACS_VLINE, 1);      }      col+=8;    }    if (showlength) {      min = cur->time/60;      sec = cur->time%60;      mvwprintw(swin, ln+2, col+3, "%3i:%02i", min, sec);      if (num==j) {	wmove(swin, ln+2, col+1);	wvline(swin, ACS_VLINE, 1);      }      col+=9;    }    switch (showsize) {    case 1:      mb = ((float)cur->sz)/1048576.0;      mvwprintw(swin, ln+2, col+3, "%6.02f", mb);      if (num == j) {	wmove(swin, ln+2, col+1);	wvline(swin, ACS_VLINE, 1);      }      col += 9;      break;    case 2:      mvwprintw(swin, ln+2, col+3, "%9d", cur->sz);      if (num == j) {	wmove(swin, ln+2, col+1);	wvline(swin, ACS_VLINE, 1);      }      col += 12;      break;    case 0: default:      break;    }    if (showfreq) {      mvwprintw(swin, ln+2, col+3, "%5i", cur->freq);      if (num==j) {	wmove(swin, ln+2, col+1);	wvline(swin, ACS_VLINE, 1);      }      col+=8;    }    if (showuser) {      mvwprintw(swin, ln+2, col+3, "%s", cur->nick);      if (num==j) {	wmove(swin, ln+2, col+1);	wvline(swin, ACS_VLINE, 1);      }      col+=3+usercols;    }    if (showconn) {      mvwprintw(swin, ln+2, col+3, cur->conn != -1 ? conns[cur->conn] : "N/A");      if (num==j) {	wmove(swin, ln+2, col+1);	wvline(swin, ACS_VLINE, 1);      }      col+=12;    }    if (showping) {      mvwprintw(swin, ln+2, col+3, cur->ping>=0 ? "%4i" : " N/A", cur->ping);      if (num==j) {	wmove(swin, ln+2, col+1);	wvline(swin, ACS_VLINE, 1);      }      col+=7;    }        if (num == j)      wattroff(swin, COLOR_PAIR(1)|A_BOLD);      } /* end for j */    sl_draw();  drw(swin);  if (t)    free(t);}/* handle input on result screen */int sinput(WINDOW *win, sock_t *m){  chtype cbuf = 0;  WINDOW *w = swin;  cbuf = wgetch(w);  if (cbuf == '\e') {                   /* ESC */    cbuf = wgetch(w);    if (cbuf == ERR)      return(1);    else      cbuf+=128;  }  if (!sl_handle_keystroke(cbuf))    shandlechar(cbuf);  plist();  return(1);}/* handle key stroke on result screen */int shandlechar(chtype ch){  sock_t *sk;  ssearch_t *cur, *a, *b;  int r;  const char *help =     "HELP - use <right> and <left> to scroll this information. "    "<up> and <down> to move cursor. <return> to download item. "    "q to return to main screen. "    "F1-F3 or M-1 thru M-3 to switch between screens. "    "<tab> to switch between results and dl/ul screens. "    "<space> to enter a new search. "    "'/' to goto main screen and start a command. "    "l/b/m/f/u/s/p/a/n to toggle information displayed. "    "N/D/L/B/M/F/U/S/P to sort. h for help.";    switch (ch) {  case KEY_F(1):                        /* F1 */  case 128 + '1':                       /* M-1 */  case 'q':    switchtoscreen(MAIN_SCREEN);    break;  case KEY_F(3):                        /* F3 */  case 128 + '3':                       /* M-3 */  case '\t':                            /* Tab */    switchtoscreen(DLUL_SCREEN);    break;  case '/':      ccmd = NULL;      strcpy(cbuf, "/");      curr = 0;      curx = strlen(cbuf);      switchtoscreen(MAIN_SCREEN);      break;  case 'h': case 'H':    sl_set(help);    lk = 1;    break;  case KEY_UP:                          /* Up */    num--;    if (num <= 0)      num = 1;    lk = 0;    break;  case KEY_DOWN:                        /* Down */    num++;    lk = 0;    break;      case KEY_PPAGE:                       /* PgUp */  case 5:                               /* Ctrl-E */  case 16:                              /* Ctrl-P */    if (nvar_default("cursorfollowsscreen", 0)) {      if (cy<=1) {	sl_set("Beginning of search results");	lk = 1;      } else {           /* one screen up, cursor follows screen */	cy -= LINES-4;	if (cy<1) {	  cy = 1;	}	if (num >= (LINES-3)+cy) {	  num = cy+(LINES-3)-1;	}	lk = 0;      }    } else {             /* screen follows cursor policy */      if (num <= 1) {	sl_set("Beginning of search results");	lk = 1;      } else {		num -= LINES-4;	if (num <= 0)	  num = 1;	lk = 0;      }    }    break;  case KEY_NPAGE:                       /* PgDn */  case 4:                               /* Ctrl-D */  case 14:                              /* Ctrl-N */  case 22:                              /* Crtl-V */    if (nvar_default("cursorfollowsscreen", 0)) {      if (cy>=max-(LINES-3)+1) {	sl_set("End of search results");	lk = 1;      } else {           /* one screen down, cursor follows screen */	cy += LINES-4;	if (cy>max-(LINES-3)+1) {	  cy = max-(LINES-3)+1;	}	if (num < cy) {	  num = cy;	}	lk = 0;      }    } else {              /* screen follows cursor policy */      if (num>=max) {	sl_set("End of search results");        lk = 1;      } else {	num += LINES-4;	lk = 0;      }    }    break;  case 12:                              /* Ctrl-L */    clearok(swin, 1);    wrefresh(swin);    break;  case '\n':    if (search)    {      lk = 1;      list_nth(cur, search, num-1);      if (cur)      {	sk = findsock("server");	if (sk)        {	  r = requestdownload(sk->fd, cur);	  switch(r) {	  case 0:	    sl_sprintf("Getting %s", cur->song);	    wp(wchan, "* Getting \"%s\" from %s\n", cur->song, cur->nick);	    break;	  case 1: case 2:	    sl_sprintf("Queued %s", cur->song);	    wp(wchan, "* Queued download of \"%s\" from %s\n", cur->song, cur->nick);	    	    break;	  case 3:	    sl_sprintf("Remotely queued %s", cur->song);	    wp(wchan, "* Remotely queued download of \"%s\" from %s\n", cur->song, cur->nick);	    	    break;	  case -1:	    sl_sprintf("Already getting %s", cur->song);	    break;	  case -2:	    sl_sprintf("Already queued %s", cur->song);	    break;	  case -3:	    sl_set("Can't get a file from yourself!");	    break;	  default:	    break;	  }	}	else /* !sk */	{	  sl_set("Not connected to server");	}      }       else /* !cur */      {	sl_set("Error: No matching item in search list??");      }    } /* end if(search) */    break;  case 'l':    showlength = 1-showlength;    break;  case 'b':    showbrate = 1-showbrate;    break;  case 'm':    showsize = (showsize + 1) % 3;    break;  case 'f':    showfreq = 1-showfreq;    break;  case 'u':    showuser = 1-showuser;    break;  case 's':    showconn = 1-showconn;    break;  case 'p':    showping = 1-showping;    break;  case 'a':    showlength = showbrate = showfreq = 1;    showconn = showping = showuser = 1;    showsize = showsize ? showsize : 1;    break;  case 'n':    showlength = showbrate = showsize = showfreq = 0;    showconn = showping = showuser = 0;    break;  case 'N':  /* various ways to sort */  case 'D':  case 'L':  case 'B':  case 'M':  case 'F':  case 'U':  case 'S':  case 'P':    /* remember which item the cursor was on */    list_nth(cur, search, num-1);        if (ch == lastsort) {                 /* reverse? */      list_reverse(ssearch_t, search);    } else {                                /* sort */      lastsort = ch;      /* this looks awful, but list_mergesort is a fairly large macro,	 and expanding it 7 times would probably be a worse option */      list_mergesort(ssearch_t, search, a, b,		     (ch=='N' && strcasecmp(a->song, b->song) <= 0)		     || (ch=='D' && strcasecmp(a->rfn, b->rfn) <= 0)		     || (ch=='L' && a->time <= b->time)		     || (ch=='B' && a->brate <= b->brate)		     || (ch=='M' && a->sz <= b->sz)		     || (ch=='F' && a->freq <= b->freq)		     || (ch=='U' && strcasecmp(a->nick, b->nick) <= 0)		     || (ch=='S' && a->conn <= b->conn)		     || (ch=='P' && (b->ping == -1 || 				       (a->ping != -1 && a->ping <= b->ping)))		     );    }    /* put the cursor back where it was */    if (cur) {      list_index(search, num, a, a==cur);      num++;      if (num >= (LINES-3)+cy || num < cy) {	cy = num-(LINES-3)/2;	if (cy<1)	  cy = 1;      }    }    break;      default:    break;  }  return(1);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -