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

📄 zbrowse.c

📁 unix下的界面工具
💻 C
字号:
#include  <stdio.h>
#include  <malloc.h>
#include  "zlib.h"

typedef struct
{
  int (*p)();
} ZPROC;
typedef struct
{
  int k;
  char *l;
} ZBUTL;
typedef struct
{
  void *s;
  ZBROWSE *b;
  ZPROC n;
  ZPROC *k;
} ZBRWS;

static ZBRWS *S;
static ZBROWSE *B;
static ZBUTL CtrlKey[]=
{
  { UP,    "↑上行"   },
  { DOWN,  "↓下行"   },
  { LEFT,  "←左列"   },
  { RIGHT, "→右列"   },
  { HOME,  "Home首页" },
  { END,   "End 末页" },
  { PGUP,  "PgUp前页" },
  { PGDN,  "PgDn次页" },
  { '8',   "8-上行"   },
  { '2',   "2-下行"   },
  { '4',   "4-左列"   },
  { '6',   "6-右列"   },
  { '7',   "7-首页"   },
  { '1',   "1-末页"   },
  { '9',   "9-前页"   },
  { '3',   "3-次页"   }
};

static void GetPage()
{
  int i;

  B->lc = 0;
  for( i = 0; i < B->rr * B->rc; i ++ )
  {
    if( ( !B->gl || ( *B->gl )( i ) ) && B->el )
      ( *B->el )();
    B->lc ++;
    if( i == B->rr * B->rc - 1 || !B->nl || ( *B->nl )() )
      break;
  }
}

static void EmptyRest()
{
  int i;

  if( B->el )
    for( i = B->lc; i < B->rr * B->rc; i ++ )
      ( *B->el )( i );
}

static void DispCursor()
{
  if( B->dl && B->lc > 0 )
  {
    ZWattr( ZA_SELBAR );
    ( *B->dl )( B->cl );
    ZWattr( ZA_TEXT );
  }
  if( B->cc )
    ( *B->cc )();
}

static void DispPage()
{
  int i;

  if( B->dl )
    for( i = 0; i < B->rr * B->rc; i ++ )
      ( *B->dl )( i );
  if( B->cl >= B->lc )
    B->cl = B->lc - 1;
  if( B->cl < 0 )
    B->cl = 0;
  DispCursor();
}

static int BackLine( int Lines )
{
  int i;

  if( !B->pl || !B->sl || !B->gl )
    return( 0 );
  for( i = 0; i < Lines; i ++ )
  {
    if( ( *B->sl )( 0 ) )
      break;
    if( ( *B->pl )() )
      break;
    if( ( *B->gl )( 0 ) )
      break;
  }
  if( ( *B->sl )( 0 ) )
    return( 0 );
  return( i );
}

static int RoundPage()
{
  int l, c;

  if( B->lc < 0 )
    B->lc = 0;
  else{
    l = -1;
    while( l != B->lc )
    {
      GetPage();
      l = B->lc;
      if( l < B->rr * B->rc )
      {
        c = BackLine( B->rr * B->rc - l );
        B->lc += c;
        B->cl += c;
      }
    }
    if( B->lc == 1 && B->ur )
      return( ( *B->ur )() );
  }
  return( 0 );
}

static int NewPage()
{
  int r;

  r = RoundPage();
  if( r )
    return( r );
  EmptyRest();
  DispPage();
  return( 0 );
}

static void ChangeCursor( int New )
{
  if( B->dl )
    ( *B->dl )( B->cl );
  B->cl = New;
  DispCursor();
}

static int KeyValid( int Key )
{
  int r;

  if( B->st )
    return( -1 );
  r = 0;
  switch( Key )
  {
  case UP:
  case '8':
    if( B->cl < B->rc && !BackLine( B->rc ) )
      r = -1;
    break;
  case DOWN:
  case '2':
    if( B->cl >= B->lc - B->rc && ( B->lc < B->rr * B->rc || !B->sl || ( *B->sl )( B->lc - 1 ) || !B->nl || ( *B->nl )() || !B->sl || ( *B->sl )( B->rc ) ) )
      r = -1;
    break;
  case LEFT:
  case '4':
    if( !B->cl && ( !B->sl || ( *B->sl )( 0 ) || !B->pl || ( *B->pl )() ) )
      r = -1;
    break;
  case RIGHT:
  case '6':
    if( B->cl + 1 >= B->lc && ( B->lc < B->rr * B->rc || !B->sl || ( *B->sl )( B->lc -1 ) || !B->nl || ( *B->nl )() || !B->sl || ( *B->sl )( 1 ) ) )
      r = -1;
    break;
  case HOME:
  case '7':
    if( !B->sl || ( *B->sl )( 0 ) || !B->pl || ( *B->pl )() || !B->fl || ( *B->fl )() )
      r = -1;
    break;
  case END:
  case '1':
    if( B->lc < B->rr * B->rc || !B->sl || ( *B->sl )( B->lc - 1 ) || !B->nl || ( *B->nl )() || !B->ll || ( *B->ll )() )
      r = -1;
    break;
  case PGUP:
  case '9':
    if( !BackLine( B->rr * B->rc ) )
      r = -1;
    break;
  case PGDN:
  case '3':
    if( B->lc < B->rr * B->rc || !B->sl || ( *B->sl )( B->lc - 1 ) || !B->nl || ( *B->nl )() )
      r = -1;
    break;
  }
  return( r );
}

static int KeyHit( int Key )
{
  switch( Key ){
  case UP:
  case '8':
    if( B->cl >= B->rc )
      ChangeCursor( B->cl - B->rc );
    else
      NewPage();
    break;
  case DOWN:
  case '2':
    if( B->cl < B->lc - B->rc )
      ChangeCursor( B->cl + B->rc );
    else
      NewPage();
    break;
  case LEFT:
  case '4':
    if( B->cl > 0 )
      ChangeCursor( B->cl - 1 );
    else
      NewPage();
    break;
  case RIGHT:
  case '6':
    if( B->cl + 1 < B->lc )
      ChangeCursor( B->cl + 1 );
    else
      NewPage();
    break;
  case HOME:
  case '7':
  case END:
  case '1':
  case PGUP:
  case '9':
  case PGDN:
  case '3':
    NewPage();
    break;
  }
  return( -1 );
}

static int CheckStatus( int Key, int Number )
{
  if( B->st )
    return( -1 );
  if( !( S->k + Number )->p )
    return( 0 );
  return( ( *( S->k + Number )->p )( Key, Number ) );
}

static int StartUp()
{
  if( B->fl && ( *B->fl )() )
  {
    if( B->nr )
      return( ( *B->nr )() );
    else
      B->lc = -1;
  }
  return( 0 );
}

static int EndOver()
{
  if( B->ll && ( *B->ll )() )
  {
    if( B->nr )
      return( ( *B->nr )() );
    else
      B->lc = -1;
  }
  return( 0 );
}

static int IdleProc()
{
  int r;

  if( B->st )
  {
    switch( B->st )
    {
    case ZI_CURSOR:
      if( ( !B->sl || ( *B->sl )( B->cl ) || !B->gl || ( *B->gl )( B->cl ) ) && B->el )
        B->el( B->cl );
      DispCursor();
      break;
    case ZI_PAGE:
      if( ( r = NewPage() ) != 0 )
        return( r );
      break;
    case ZI_FIRST:
      if( ( r = StartUp() ) != 0 )
        return( r );
      if( ( r = NewPage() ) != 0 )
        return( r );
      break;
    case ZI_LAST:
      if( ( r = EndOver() ) != 0 )
        return( r );
      if( ( r = NewPage() ) != 0 )
        return( r );
      break;
    }
    B->st = 0;
  }
  if( B->dc && !( *B->dc )() )
  {
    while( B->lc && B->sl && ( *B->sl )( B->cl ) )
      if( B->cl )
        B->cl --;
      else
        B->lc = 0;
    if( B->lc )
      B->cl = BackLine( B->cl );
    else if( ( r = EndOver() ) != 0 )
      return( r );
    if( ( r = NewPage() ) != 0 )
      return( r );
  }
  if( S->n.p )
    return( ( *S->n.p )( B->s->fc, 0 ) );
  return( 0 );
}

static void SetButton( ZBUTTON *B, int C, ZBUTL *L )
{
  int i;

  if( ( i = ZBkey( B, C, L->k ) ) >= 0 )
  {
    if( !( B + i )->l )
      ( B + i )->l = L->l;
    if( !( B + i )->v )
      ( B + i )->v = KeyValid;
    if( !( B + i )->p )
      ( B + i )->p = KeyHit;
  }
}

static void ResetButton( ZBUTTON *B, int C, ZBUTL *L )
{
  int i;

  if( ( i = ZBkey( B, C, L->k ) ) >= 0 )
  {
    if( ( B + i )->l == L->l )
      ( B + i )->l = 0;
    if( ( B + i )->v == KeyValid )
      ( B + i )->v = 0;
    if( ( B + i )->p == KeyHit )
      ( B + i )->p = 0;
  }
}

static void BeforeExec()
{
  int i;
  ZBUTTON *p;
  int c;

  p = B->s->bs;
  c = B->s->bc;
  for( i = 0; i < sizeof( CtrlKey ) / sizeof( ZBUTL ); i ++ )
    SetButton( ( ZBUTTON * ) p, c, CtrlKey + i );
  for( i = 0; i < c; i ++ )
    if( ( ( ZBUTTON * ) p + i )->v != KeyValid )
    {
      ( S->k + i )->p = ( ( ZBUTTON * ) p + i )->v;
      ( ( ZBUTTON * ) p + i )->v = CheckStatus;
    }
  S->n.p = B->s->nk;
  B->s->nk = IdleProc;
}

static void AfterExec()
{
  int i;
  ZBUTTON *p;
  int c;

  B->s->nk = S->n.p;
  p = B->s->bs;
  c = B->s->bc;
  for( i = 0; i < c; i ++ )
    if( ( ( ZBUTTON * ) p + i )->v == CheckStatus )
      ( ( ZBUTTON * ) p + i )->v = ( S->k + i )->p;
  for( i = 0; i < sizeof( CtrlKey ) / sizeof( ZBUTL ); i ++ )
    ResetButton( ( ZBUTTON * ) p, c, CtrlKey + i );
}

int Zbrowse( ZBROWSE *BS )
{
  int   r;
  ZBRWS  *t;

  if( ( t = ( ZBRWS * ) malloc( sizeof( ZBRWS ) ) ) == NULL )
    return( 0 );
  t->s = S;
  S = t;
  B = S->b = BS;
  S->k = NULL;
  if( ( S->k = ( ZPROC * ) malloc( B->s->bc * sizeof( int * ) ) ) == NULL )
    goto Exit;
  B->cl = 0;
  if( ( r = StartUp() ) != 0 )
    goto Exit;
  if( ( r = RoundPage() ) != 0 )
    goto Exit;
  if( ZWopen( B->wp ) )
    goto Exit;
  if( B->ds )
    ( *B->ds )();
  EmptyRest();
  DispPage();
  BeforeExec();
  r = Zscreen( B->s );
  AfterExec();
  ZWclose();
Exit:
  if( S->k != NULL )
    free( S->k );
  t = S->s;
  free( S );
  S = t;
  B = S->b;
  return( r );
}

⌨️ 快捷键说明

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