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

📄 winio.c

📁 P2P NAP的C实现 P2P在网络应用中越来越流行
💻 C
📖 第 1 页 / 共 3 页
字号:
/* Copyright (c) 2000  Kevin Sullivan <nite@gis.net> * * Please refer to the COPYRIGHT file for more information. *//* this file contains procedures related to the main window: drawing,   redrawing, scrolling, user input, etc. */#ifdef HAVE_CONFIG_H# include <config.h>#endif#define _GNU_SOURCE /* needed for stdio.h:vasprintf */#include <stdio.h>#include <stdlib.h>#include <ctype.h>#include <termios.h>#include <ncurses.h>#include <string.h>#include <sys/ioctl.h>#include <netdb.h>#include <time.h>#include "defines.h"#include "codes.h"#include "nap.h"#include "colors.h"#include "winio.h"#include "alias.h"#include "irc.h"#include "lists.h"#include "scheck.h"#include "sscr.h"#include "dlul_screen.h"#include "missing.h"#ifdef MEMWATCH  #include "memwatch.h"#endifextern info_t info;extern int ircmode, wmode;extern chans_t *curchan;    /* current channel, if any */extern upload_t *up;    /* download task list */extern download_t *down;    /* download task list */extern scount_t scount;     /* libraries, songs, gigs */extern char *mnick;extern int noprint;extern int ircsock;extern alias_t *alhead;     /* alias list */extern out_nap_cmd_t out[]; /* list of builtin commands */extern WINDOW *swin;/* the new model for managing input screens is as follows: *//* the number of the currently active screen. Currently three values   are possible: MAIN_SCREEN, RESULT_SCREEN, and DLUL_SCREEN. However,   further screens may be added in the future (such as: resume screen,   configuration screen) */int screen;/* Each screen has its own curses windows, and its own global state   (such as: scroll buffer, command history, and input state for main   screen, search item under cursor, displayed information categories,   etc, for search screen). When switching screens, it is equally   important to switch the input focus. In the new model, there is   only one "input" connection which remains active at all times, but   its "func" component is set to a different handler for different   screens. Its "d" component is not used. It is imperative to update   the "screen" variable and this handler at the same time, or else   the user input will be directed to an invisible screen. *//* individual screens may choose to delete their curses windows when   they are not switched on (the search result screen does this), or   to retain them (the main screen does it this way). *//* each screen should provide a procedure for switching it on   (initializing its state, windows, and input handler) and for   switching it off (deleting any part of the state that is not   needed). The function switchscreen(n) switches to screen number n,   setting "screen" as appropriate, and calling the individual   screen's off and on routines. *//* curses windows and global state for main screen */WINDOW *wchan=NULL, *winput, *sep, *whead;int tind = 0;                 /* indentation of the title (channel topic) */chans_t *recent = NULL;       /* most recent channel; (always NULL) */scroll_t *mscroll = NULL;      /* top of the main scroll */scroll_t *mscrollend = NULL;   /* bottom of the main scroll */scroll_t *scur = NULL;         /* last line now displayed, or NULL for end */int mscrollsize = 0;           /* length of the main scroll */int lastlogflag = 0;           /* set to 1 during output of "lastlog"				  command - this causes these lines to				  be marked and ignored in future				  "lastlog" commands. *//* the command history */cmds_t *cmdl, *cmdlend = NULL; /* A doubly linked list of lines,				  possibly empty. This is read-only,				  except that new lines can be				  appended at the end, and the total				  length of the list is bounded by				  BACKLOG. */int cmdlsize = 0;              /* length of the command history */cmds_t *ccmd = NULL;          /* a pointer to the line in cmdl which				 the current edit is based on, or NULL if				 the current edit is from scratch */unsigned char cbuf[512];      /* the line currently being edited */unsigned char cscratch[512];  /* a place where the current "from scratch"				 line is saved if ccmd != NULL */int curr = 0;                 /* first char of cbuf displayed on screen */int curx = 0;                 /* cursor position in cbuf *//* global state for search screen is defined in sscr.c */colortab_t colortab[] = {  { RED, CPR, 1 },  { GREEN, CPG, 1 },  { WHITE, CPW, 1 },  { BLUE, CPB, 1 },  { YELLOW, CPY, 1 },  { MAGENTA, CPM, 1 },  { CYAN, CPC, 1, },  { BOLD, A_BOLD, 0 },  { DARK, A_DIM, 0 },  { BLINK, A_BLINK, 0 },  { UNDERLINE, A_UNDERLINE, 0 },  { NULL, -1, 0 }};/* switch to screen number n (which should be MAIN_SCREEN,   RESULT_SCREEN, or DLUL_SCREEN). Returns 0 if we already were on   that screen (without redrawing it), 1 if there was a real switch,   and -1 on error. */int switchtoscreen(int n) {  if (n==screen) {    return 0;  }  /* check that screen selected is valid */  switch (n) {  case MAIN_SCREEN:  case RESULT_SCREEN:  case DLUL_SCREEN:    break;  default:    return(-1);  }  /* turn off old screen */  switch (screen) {  case MAIN_SCREEN:    /* nothing to do */    break;  case RESULT_SCREEN:    endsearchscr();    break;  case DLUL_SCREEN:    enddlulscr();    break;  default:    return(-1);    break;  }  screen = n;  /* turn on new screen */  switch (n) {  case MAIN_SCREEN:    mainscr();    break;  case RESULT_SCREEN:    searchscr();    break;  case DLUL_SCREEN:    dlulscr();    break;  default: /* not reachable */    return(-1);    break;  }  return(1);}/* switch to the next available screen */int nextscreen(void) {  switch(screen) {  case MAIN_SCREEN:    switchtoscreen(RESULT_SCREEN);    break;  case RESULT_SCREEN:    switchtoscreen(DLUL_SCREEN);    break;  case DLUL_SCREEN:  default:    switchtoscreen(MAIN_SCREEN);    break;  }  return(1);}/* switch to main screen */void mainscr(void) {  sock_t *sk;  sk = findsock("input");  if (sk) {    sk->func = input;  }  dscr(wchan);  drw(wchan);  dstatus();  indraw();}void resize(){  sock_t *t;  struct winsize ws;  memset(&ws, 0, sizeof(ws));  ioctl(fileno(stdin), TIOCGWINSZ, &ws);    resizeterm(ws.ws_row, ws.ws_col);  winput->_begy = LINES-1;  winput->_begx = 0;  sep->_begy = LINES-2;  sep->_begx = 0;  if (info.notop)    wresize(wchan, LINES-2, COLS);  else    wresize(wchan, LINES-3, COLS);  wresize(winput, 1, COLS);  if (!info.notop)    wresize(whead, 1, COLS);  wresize(sep, 1, COLS);  drw(wchan);  drw(sep);    dstatus();    /* redraw input screen */  werase(winput);  t = findsock("input");  if (t) {    indraw();  }  dscr(wchan);  drw(wchan);  drw(winput);  if (screen==RESULT_SCREEN) {    plist();  }  else if (screen == DLUL_SCREEN) {    dlul_refresh();  }      return;}void wstats(WINDOW *win){  wp(win, "stdscr to %i - %i\n", stdscr->_maxy, stdscr->_maxx);  wp(win, "winput to %i - %i\n", winput->_maxy, winput->_maxx);  wp(win, "sep to %i - %i\n", sep->_maxy, sep->_maxx);  wp(win, "wchan to %i - %i\n", wchan->_maxy, wchan->_maxx);  wp(win, "LINES/COLS to %i - %i\n", LINES, COLS);  drw(win);}void drw(WINDOW *win){  if (info.daemon || !win)    return;    if (screen==RESULT_SCREEN && win == swin)    wrefresh(win);  else if (screen==DLUL_SCREEN && win == dlul_win)    wrefresh(win);  else if (screen==MAIN_SCREEN)    wrefresh(win);}void dstatus(){  int j, lg;  char *t = NULL;  user_t *cur;  int nu, nd, ndq;  download_t *dtask;  upload_t *utask;  list_count(down, nd, dtask, ACTIVE(dtask->state) && dtask->state!=RRQUEUED);  list_count(down, ndq, dtask, dtask->state == QUEUED || dtask->state == RQUEUED || dtask->state == RRQUEUED);  list_count(up, nu, utask, !STOPPED(utask->state));  if (info.daemon) {    return;  }  werase(sep);  if (!info.notop)    werase(whead);  for (j=0;j<COLS;j++)  {    waddch(sep, ' ');    if (!info.notop)      waddch(whead, ' ');  }    if ((!ircmode && !curchan) || (curchan && (!curchan->q || curchan->q == 1)))  {    msprintf(&t, "[U/%i D/%i Q/%i]", nu, nd, ndq);    mvwprintw(sep, 0, COLS-(strlen(t)+1), t);    free(t);    mvwprintw(sep, 0, 0, cloaked ? " (%s)" : " [%s]", info.user);    wprintw(sep, scount.songs == 1 ? " [%lu song" : " [%lu songs", scount.songs);    wprintw(sep, scount.libraries == 1 ? " in %lu library" : " in %lu libraries", scount.libraries);    wprintw(sep, scount.gigs == 1 ? " (%lu gig)]" : " (%lu gigs)]", scount.gigs);  }  else  {    if (!curchan || !curchan->users)      mvwprintw(sep, 0, 0, " [%s]", mnick);    else if (curchan->flag)    {      t = strdup(curchan->nm);      if (strlen(curchan->nm) > COLS/4)        t[COLS/4] = 0;      cur = finduser(curchan, mnick);      if (cur->flag & NAP_OP)        mvwprintw(sep, 0, 0, " [@%s] [%s +", mnick, t);      else if (cur->flag & NAP_VOICE)        mvwprintw(sep, 0, 0, " [+%s] [%s +", mnick, t);      else        mvwprintw(sep, 0, 0, " [%s] [%s +", mnick, t);      if (curchan->flag & NAP_I)        waddch(sep, 'i');      if (curchan->flag & NAP_S)        waddch(sep, 's');      if (curchan->flag & NAP_P)        waddch(sep, 'p');      if (curchan->flag & NAP_T)        waddch(sep, 't');      if (curchan->flag & NAP_M)        waddch(sep, 'm');      if (curchan->flag & NAP_N)        waddch(sep, 'n');      if (curchan->flag & NAP_K)        waddch(sep, 'k');      if (curchan->flag & NAP_L)        waddch(sep, 'l');      if (curchan->flag & NAP_K || curchan->flag & NAP_L)        waddch(sep, ' ');      if (curchan->flag & NAP_K)        wprintw(sep, "%s", curchan->key);      if (curchan->flag & NAP_K && curchan->flag & NAP_L)        waddch(sep, ' ');      if (curchan->flag & NAP_L)        wprintw(sep, "%i", (unsigned int)curchan->l);      waddch(sep, ']');      free(t);      t = NULL;    }    else    {      t = strdup(curchan->nm);      if (strlen(curchan->nm) > COLS/4)        t[COLS/4] = 0;      cur = finduser(curchan, mnick);      if (cur->flag & NAP_OP)        mvwprintw(sep, 0, 0, " [@%s] [%s]", mnick, t);      else if (cur->flag & NAP_VOICE)        mvwprintw(sep, 0, 0, " [+%s] [%s]", mnick, t);      else        mvwprintw(sep, 0, 0, " [%s] [%s]", mnick, t);      free(t);      t = NULL;    }  }    if (!info.notop) {    lg = COLS-(strlen(VERSION)+8)-4;    if (lg >= 0) {      mvwprintw(whead, 0, COLS-(strlen(VERSION)+8), "[nap v%s]", VERSION);      if (curchan && curchan->q != 1 && curchan->topic) {	t = (char *)malloc(lg+1);	memset(t, 0, lg+1);	if (strlen(curchan->topic) < lg + tind) {	  /* drw(wchan); */ /* why here? */	  tind = strlen(curchan->topic)-lg;	}	if (tind < 0)	  tind = 0;	if (tind + lg < strlen(curchan->topic)) {	  strncpy(t, curchan->topic+tind, lg-3);	  mvwprintw(whead, 0, 0, " [%s...]", t);	} else {	  strncpy(t, curchan->topic+tind, lg);	  mvwprintw(whead, 0, 0, " [%s]", t);	}	free(t);      } else if (curchan && curchan->q == 1)	mvwprintw(whead, 0, 0, " [Query (%s)]", curchan->nm);      if (screen == MAIN_SCREEN)	wnoutrefresh(whead);    }  }  if (screen == MAIN_SCREEN)  {    wnoutrefresh(sep);    doupdate();  }}/* add the string STR to the given LOGFILE. If RP is set, replace   escape sequences */void addlog(char *logfile, char *str, int rp){  FILE *f;  int i, k;  static int bol = 1;      /* are we at the beginning of a line? */  time_t ct;  struct tm *r;  /* note: some extra care is taken to print the date and time just     before a line is printed, and not just after one is printed,     although that would have been easier. */  ct = time(NULL);  r = localtime(&ct);  f = fopen(logfile, "a");  if (!f) {    return;  }  if (!rp) {    fputs(str, f);    return;  }  for (i=0;str[i];i++) {    if (bol) {      fprintf(f, "[%02i/%02i %i:%02i] ", r->tm_mon+1, r->tm_mday, r->tm_hour, r->tm_min);      bol = 0;    }    if (str[i] == '\e') {      for (k=0; str[i] && str[i]!='m' && k<6; k++, i++) ;      continue;    }    fputc(str[i], f);    if (str[i] == '\n') {      bol = 1;    }  }    fclose(f);}int wp(WINDOW *win, const char *fmt, ...){  va_list args;  char *str;  int i;    if (noprint == 2)    return(0);    str = NULL;  va_start(args, fmt);  vasprintf(&str, fmt, args);  va_end(args);    if (info.logallfile)    addlog(info.logallfile, str, 1);      if (win && !info.daemon)  {    addscroll(win, str);    if (nvar_default("noscroll", 0)==0) {      scur = NULL;           /* be sure to scroll to bottom on output */    }    dscr(win);  }  if (!win && info.daemon!=2) {    printf("%s", str);    fflush(stdout); /* flushing here helps OpenBSD, which will                       otherwise not flush automatically before                       reading password. -PS */  }    i = strlen(str);  free(str);  return(i);}/* examines string s for escape sequences and returns a (statically   allocated) string which represents the escape sequences (color,   boldface) in effect at the end of string s. If end!=NULL, s is   considered to end there. */char *esc_getcolor(char *s, char *end) {  static char out[11] = BOLD;

⌨️ 快捷键说明

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