Logo Search packages:      
Sourcecode: xcingb version File versions  Download package

inp.c

/*
      Copyright (C) 1994,1995  Edward Der-Hua Liu, Hsin-Chu, Taiwan
*/

#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <unistd.h>
#include <X11/keysym.h>
#include <sys/stat.h>
#include "xi.h"
#include "state.h"
#include "valid.c"

#define b2cpy( a, b) memcpy( a, b, 2)
#define key_col(cha) ( ( (u_long)strchr( keyrow, cha) -(u_long) keyrow ) % 10 )

#ifndef SEEK_SET
#define SEEK_SET 0
#endif

extern void bell( int bell_kind );
extern void free( void *ptr );
extern void putstr( u_char *s );
extern void sendkey_b5( u_char *s );
extern void *malloc( size_t size );
extern void *realloc( void *ptr, size_t size );
extern void change_window_name( char *str );
extern void gotoxy( int x, int y );
extern void set_att( u_char att );
extern void SORTFUNC( void *, size_t, size_t,
            int (*compar)( const void *, const void *) );
extern char *getenv( const char *name );
extern char *tabfname[], tabdir[];
extern char *showfname;
extern char visual_bell;
extern char wildmode;
extern char system_last_full;
extern char clear_wrong;
extern int NowMax;
extern int cursor_x;
extern int show_keys[];
extern int show_keys_n;
extern int cur_show_keys;
extern int access(const char *pathname, int mode);
extern InmdState inmdstate;
extern u_char fullchar[];

typedef struct {

      ITEM *tbl;
      int KeyS;               /* 本输入法所需要的按键数     */
      int MaxPress;                 /* 本输入法最高码数           */
      int DefChars;                 /* 本输入法被定义的字和词的数目 */

      int use_quick;                /* 记录本输入法是否有定义     */
                              /* quick-code。行列三十会用到 */
                              /* 这个功能             */ 

      int phrnum;             /* 本输入法被定义的词的数目   */
      int M_DUP_SEL;                /* 一次最多可以有几个待选字   */
      int phn ;               /* 加字加词档一共有几笔资料 */
      int *idx;               /* 加字加词档的资料 */
      u_char quick1[46][10][2];     /* quick-code 模式下的资料    */
      u_char keymap[128];           /* 记载了那些键被定义         */
      u_char keyname[128];          /* 被定义的键的全形字         */
      u_char *sel1st;
      u_char keycol[50];
      u_short kmap[128];
      u_short idx1[51];
      char cname[CIN_CNAME_LENGTH]; /* 输入法的中文名字           */
      char ename[CIN_ENAME_LENGTH]; /* 输入法的英文名字           */
      char selkey[SELECT_KEY_LENGTH];     /* 选字所需要的按键           */
      char endkey[END_KEY_LENGTH];  /* 「结束键」                 */
      char keyvvv[65];
      char last_full;               /* 满字根後的空白键是否要忽略?     */
                              /* 1: 忽略              */
                              /* 0: 不忽略(照样送出空白字元)*/

      char NoBosh;                  /* 是否要用「先上字」模式?   */
                              /* 1: 不要              */
                              /* 0: 要                */

      FILE *fp;               /* .rev 档,供反查码之用      */

      FILE *fphr;             /* .phr 档。在 .cin 档中如果  */
                              /* 有定义片语的话就会用到这个档 */

} INMD;

static INMD inmd[10], *cur_inmd;
static INMD showinmd;
static char seltab[12][MAX_CIN_PHR];
static char keyrow[]=           /* for array30-like quick code */
            "qwertyuiop"
            "asdfghjkl;"
            "zxcvbnm,./";
static int defsel=0;
static u_long inch[15];
static u_char inch_box[15];
static int cin;
static int ci;
static int last_full, last_idx, now_idx;
static int more_pg,pg_idx, m_pg_mode,last_page;
static int sel1st_i;
static int spc_pressed=0;
/*
static int number_of_boshiamy_key_count=0;
static int number_of_boshiamy_word_count=0;
*/
static u_short revidx[256];
static u_char *ph;
static int Disp_opt(int, int);
static short int wild_mode;
static short int wild_page;
static short int wild_next_page;
char actual_path[MAX_PATH_LENGTH];


static int qcmp_voc( a, b )
  int *a, *b;
{
  return strcmp( &ph[ *a ], &ph[ *b ]);
}


char vvvv_fopen(FILE **fp,char *s)
{
  char sss[MAX_PATH_LENGTH], ttt[MAX_PATH_LENGTH], uuu[MAX_PATH_LENGTH];
  char *vv;

  vv = getenv( "HOME" );
  strcpy( ttt, vv );
  strcpy( uuu, ttt );
  strcat( uuu, "/.xcin/" );

  strcpy( ttt, tabdir );

  strcpy( sss, "./" );
  strcat( sss, s );

  strcat( uuu, s );
  strcat( ttt, s );

  if( ( *fp = fopen( sss, "r" ) ) == NULL ) {

     if( ( *fp = fopen( uuu, "r" ) ) == NULL ) {

      if( ( *fp = fopen( ttt, "r" ) ) == NULL ) {

        actual_path[0] = 0;
        return -1;

      }
      else
        strcpy( actual_path, ttt);

     }
     else 
      strcpy( actual_path, uuu);

  }
  else
     strcpy( actual_path, sss);

  return 1;

}



void ClrSelArea()
{
  int i;

  gotoxy( 0, 0 );

  for( i = 0; i < COLUMN_WIDTH; i++ )
     xprintf(" ");

  gotoxy( 0, 0 );

}


static char open_vocbox( INMD *inp , int inmdno )
{
  int i, j;
  int mfree;
  int phsize;
  int len;
  int keys = inp->KeyS;
  FILE *fp;
  char tt[1024];
  char d[128];
  char *p, *q;
  char voc_file[MAX_PATH_LENGTH];

  p = strrchr( tabfname[inmdno], '/' ) + 1;

  strcpy( voc_file, p );
  voc_file[ strlen( voc_file ) - 4 ] = 0;
  strcat( voc_file, ".box" );

  if ( vvvv_fopen( &fp, voc_file ) == -1 ) {
     return -1;
  }

  strcpy( voc_file, actual_path );

  while ( !feof( fp ) ) {
     fgets( tt, sizeof( tt ), fp );
     inp->phn++;
  }

  inp->phn++;

  if ( !( inp->idx = (int *)malloc( inp->phn * sizeof(u_char *) ) ) ) {
     printf("ERROR!! malloc phrase box file %s index error\n",
            voc_file );
     return -1;
  }

  if ( !( ph = (u_char *)malloc( phsize = 1024 ) ) ) {
     printf("ERROR!! malloc phrase box file %s index error\n",
            voc_file );
     return -1;
  }

  mfree = inp->phn = 0;
  fseek( fp, 0, 0);

  while ( !feof( fp ) ) {

     fgets( tt, sizeof( tt ), fp );

     p = tt;
     len = strlen( tt );

     if ( len && tt[len-1] == '\n' )
      tt[len-1]=0;

     if ( tt[0] == '#' || tt[0] == ' ' )
      continue;

     while ( *p == 9 || *p == ' ' )
      p++;

     if ( !*p )
      continue;

     q = p;

     while ( ( *q != 9 ) && ( *q != ' ' ) && ( *q ) ) { 

      *q = tolower( *q );

      if ( inp->keymap[(int)*q] == 0 ) {

        int f;

        inp->keymap[(int) *q ]        = keys;
        inp->keymap[(int)toupper( *q )] = keys;
        f = ( (int) *q - ' ' ) << 1;
        inp->keyname[keys * 2]     = fullchar[f];
        inp->keyname[keys * 2 + 1] =fullchar[f+1];
        keys++;
        inp->KeyS++;

      } /* end  if ( inp->keymap[(int)*q] == 0 )  */

      q++;

     } /* end of  while (*q!=9 && *q!=' ' && *q) */

     if ( !*q )
      continue;

     if ( q - p > 14 )
      continue;

     if ( q - p > inp->MaxPress )
      inp->MaxPress = q - p;

     len = q - p + 1;

     if (len >= phsize - mfree ) {

      phsize += 1024;

      if ( ( ph = (char *)realloc( ph, phsize ) ) == NULL ) {
        printf("ERROR realloc Boshiamy's box file %s error\n", 
                  voc_file );
        return -1;

      }  /*  end  if ( ( ph = (char *)realloc( ph, phsize ) ) == NULL )  */

     } /*  end  if (len >= phsize - mfree )  */

     *( q++ ) = 0;
     strcpy( &ph[mfree], p );
     inp->idx[inp->phn++] = mfree;
     mfree += len;

     while ( *q == 9 || *q == ' ' )
      q++;

     if ( *q == '\n' )
      *q = 0;

     len = strlen( q );

     if ( ( *q ) && ( *( q + len - 1 ) == 13 ) ) {
      len--;
      *( q + len ) = 0;
     }  /* end  if ( ( *q ) && ( *( q + len - 1 ) == 13 ) )  */

     if ( len >= phsize - mfree ) {
      phsize += 1024;
      if ( ( ph = (char *)realloc( ph, phsize ) ) == NULL ) {

        printf("ERROR!! realloc Boshiamy's box file %s error\n",
                  voc_file );
        return -1;

      }  /* end  if ( ( ph = (char *)realloc( ph, phsize ) ) == NULL )  */

     }  /* end  if ( len >= phsize - mfree )  */

     strcpy( &ph[mfree], q );
     mfree += len + 1;

  }  /* end  while( !feof( fp ) )  */

  SORTFUNC( inp->idx, inp->phn, sizeof( inp->idx[0] ), qcmp_voc );

  fclose( fp );

  bzero( d, sizeof( d ) );

  for( i = 0; i < 128; i++ )
     inp->kmap[i] = 0xffff;

  for( i = 0; i < inp->phn; i++ ) {

     j = ph[inp->idx[i]];

     if ( !d[j] ) {

      inp->kmap[j] = i;
      d[j] = 1;

     }

  }

  inp->kmap[127] = inp->phn;

  for( i = 126; i >= 0; i-- )
     if ( inp->kmap[i] == 0xffff )
      inp->kmap[i] = inp->kmap[ i + 1 ];

  printf("               Loading phrase box: " );
  printf("%s\n\n", voc_file );

  return 0;

}


static void ClrInArea()
{
  int i;

  gotoxy( InAreaX, MROW - 1 );

  set_att( InAreaColor );
  for( i = 0; i < cur_inmd->MaxPress; i++ )
     xprintf("  ");

  set_att( NormalColor );

  last_idx = 0;
  now_idx  = 0;

}


static void ClrIn()
{
  bzero( inch,   sizeof( inch   ) );
  bzero( inch_box, sizeof( inch_box ) );
  bzero( seltab, sizeof( seltab ) );

  m_pg_mode = pg_idx = more_pg = wild_mode = wild_page = last_idx = 0;
  defsel = now_idx = spc_pressed = ci = last_page = wild_next_page = 0;

  cin =  0;

  sel1st_i = 15;
}


static void DispInArea()
{
  int i;

  gotoxy( InAreaX, MROW - 1 );
  set_att( InAreaColor );
  for( i = 0; i < ci; i++ )
     xprintf( "%c%c",
            cur_inmd->keyname[   inch[i] << 1       ], 
            cur_inmd->keyname[ ( inch[i] << 1 ) + 1 ] );

  if ( i < cur_inmd->MaxPress )
     xprintf("  ");

  set_att( NormalColor );
}

static void reset_inp()
{
  ClrIn();
  ClrInArea();
  ClrSelArea();
  last_full=0;
}


int init_tab(int inmdno, int usenow)
{
  FILE *fp;
  char ttt[MAX_PATH_LENGTH], uuu[MAX_PATH_LENGTH], version_number[256];
  int i;
  INMD *inp;
  struct TableHead th;

  if( inmdno == 14 )
     inp = &showinmd;
  else
  if ( inmdno != 10 && inmdno != 11 )
     inp = &inmd[inmdno];
  else
     return -2;

  if ( inp->tbl ) { /* table is already loaded */

     gotoxy( 0, MROW - 1 );
     xprintf( "%s", inp->cname );
     change_window_name( inp->ename );

     if( inmdno != 14 )
      cur_inmd = inp;

     reset_inp();
     DispInArea();
     gotoxy( InAreaX, MROW - 1 );
     set_att( InAreaColor );

     if ( usenow )
      for( i = 0; i < cur_inmd->MaxPress; i++ )
         xprintf("  ");

     set_att(NormalColor);
     ClrShowArea( 0 );
     NowMax = cur_inmd->MaxPress;
     return 0;

  }

  if ( inmdno != 14 ) {

     if ( inp->ename[0] == 1 )
      return -1;

     if ( MyPos( "*.tab", tabfname[inmdno], 0, 0 ) == 0 )
      strcat( tabfname[inmdno], ".tab" );

     if ( vvvv_fopen( &fp, tabfname[inmdno] ) == -1 ) {

      printf( "ERROR!!   in%d: Can't open %s \n\n",
            inmdno, tabfname[inmdno] );
      inp->ename[0] = 1;
      return -1;

     }

     fread( version_number, 1, strlen( VERSION_NUMBER ) + 1, fp );
     tabfname[inmdno] = (char *)malloc( strlen( actual_path ) + 1);
     strcpy( tabfname[inmdno] , actual_path );
     strcpy( uuu, tabfname[inmdno] );
     strcat( uuu, ".rev" );

  } /* end  if ( inmdno != 14 )  */

  else {   /* inmdno = 14, then use showfname to open the sinmd input method */

     if ( MyPos( "*.tab", showfname, 0, 0 ) == 0 )
      strcat( showfname, ".tab" );

     if ( vvvv_fopen( &fp, showfname ) == -1 ) {

      printf( "ERROR!! sinmd: Can't open %s\n", showfname );
      printf( "               lookup and find code will not function\n\n" );
      return -1;

     }

     fread( version_number, 1, strlen( VERSION_NUMBER ) + 1, fp );
/*
     showfname = (char *)malloc( strlen( actual_path ) + 1);
     strcpy( showfname , actual_path );
*/
     showfname = tabfname[inmdno] = (char *)malloc(strlen(actual_path) + 1);
     strcpy( tabfname[inmdno], actual_path );
     strcpy( uuu, showfname );
     strcat( uuu, ".rev" );

  }

  if( strcmp( VERSION_NUMBER, version_number ) ) {

     if ( inmdno != 14 ) {
      free( tabfname[inmdno] );
      tabfname[inmdno] = (char *) 0;
      printf("ERROR!!   in%d: %s is not a valid tab file\n\n",
            inmdno, actual_path );
      return -1;
     }
     else {
      free( showfname );
      showfname = (char *) 0;
      printf("ERROR!! sinmd: %s is not a valid tab file\n\n",
            actual_path );
      return -1;
     }
  }

  fread( &th, 1, sizeof( th ), fp );

  if ( inmdno == 14 ) {

     printf("xcin:   sinmd: file path is    %s\n", actual_path );
     printf("               English name is %s\n", th.ename );
     printf("               Chinese name is %s\n\n", th.cname );

  } else {

     printf("xcin:     in%d: file path is    %s\n", inmdno, actual_path );
     printf("               English name is %s\n", th.ename );
     printf("               Chinese name is %s\n", th.cname );

  }

  strcat( actual_path, ".rev" );

  if ( access( actual_path , F_OK ) != -1 ) {

     if ( inmdno == 14 )
      cur_show_keys = show_keys_n ;
     show_keys[show_keys_n++] = inmdno;

  } else
  if ( inmdno == 14 ) {

     printf("ERROR!! sinmd: Can't find      %s\n", actual_path );
     printf("               lookup and find code will not function\n\n" );

  }


  fread( ttt, 1, th.KeyS, fp );
  fread( inp->keyname, 2, th.KeyS, fp );

  inp->keyname[ 61 * 2 ]     = ' ';
  inp->keyname[ 61 * 2 + 1 ] = '?';
  inp->keyname[ 62 * 2 ]     = ' ';
  inp->keyname[ 62 * 2 + 1 ] = '*';
  inp->KeyS  = th.KeyS;
  inp->MaxPress  = th.MaxPress;
  inp->DefChars  = th.DefC;
  inp->NoBosh      = th.endian;
/*  inp->last_full = th.last_full == -1 ? system_last_full:th.last_full; */
  inp->last_full = (system_last_full == -1) ? th.last_full : system_last_full;
  if(inp->last_full == -1)
    inp->last_full = SYSTEM_LAST_FULL;
  inp->M_DUP_SEL = th.M_DUP_SEL;
  strcpy( inp->ename, th.ename );
  strcpy( inp->selkey, th.selkey );
  strcpy( inp->endkey, th.endkey );

  for( i = 0; i < th.KeyS; i++ ) {
     inp->keymap[(int) ttt[i]]          = i;
     inp->keymap[toupper( ttt[i] )] = i;
     inp->keyvvv[i] = ttt[i];
     inp->keycol[i] = key_col( ttt[i] );
  }

  if ( inmdno == 14 ) return 0;

  if ( strlen( th.cname ) > 8 )
     strcpy( ttt, th.cname );
  else {
     ttt[0] = ' ';
     strcpy( &ttt[1], th.cname );
  }

  strcpy(inp->cname, ttt);

  inp->keymap[(int)'?'] = 61;
  inp->keymap[(int)'*'] = 62;
  inp->keyvvv[61] = '?';
  inp->keyvvv[62] = '*';

  fread( inp->idx1, 2, th.KeyS + 1, fp );

  if ( ( inp->tbl = (ITEM *)malloc( sizeof( ITEM ) * th.DefC ) ) == NULL ) {
      error("Gosh, can't malloc enough memory");
      return -1;
  }

  fread( inp->tbl, sizeof( ITEM ), th.DefC, fp );
  fclose( fp );

  strcpy( ttt, tabfname[inmdno] );
  strcat( ttt, ".quick" );
  if ( ( fp = fopen( ttt, "r" ) ) != NULL ) {
      fread( inp->quick1, 2, ( th.KeyS - 1 ) * 10, fp );
      inp->use_quick = 1;
      fclose( fp );
  }

  strcpy( ttt, tabfname[inmdno] );
  strcat( ttt, ".sel1st" );
  if ( ( fp = fopen( ttt, "r" ) ) != NULL ) {
     struct stat fst;
     int fsize;

     fstat( fileno( fp ), &fst );
     fsize = fst.st_size;
     if ( inp->sel1st )
      free( inp->sel1st );
     inp->sel1st = (u_char *) malloc( fsize + 2 );
     fread( inp->sel1st, 1, fsize, fp );
     inp->sel1st[fsize] = inp->sel1st[fsize+1] = 0;
     fclose( fp );
  }

  strcpy( ttt, tabfname[inmdno] );
  strcat( ttt, ".phr" );
  if ( ( inp->fphr = fopen( ttt, "r" ) ) != NULL ) {
     fread( &inp->phrnum, 4, 1, inp->fphr );
  }

  if( inmdno != 14 ) {
      if ( open_vocbox( inp , inmdno ) == -1 )
         printf( "\n" );
  }
  else printf( "\n" );


  if ( usenow ) {
     change_window_name( inp->ename );
     cur_inmd = inp;
     NowMax = cur_inmd->MaxPress;
     reset_inp();
     gotoxy( 0, MROW - 1 );
     xprintf( "%s", inp->cname );
     gotoxy( InAreaX, MROW - 1 );
     set_att( InAreaColor );
     ClrInArea();
     DispInArea();
     gotoxy( InAreaX, MROW - 1 );
     set_att( InAreaColor );
     for( i = 0; i < cur_inmd->MaxPress; i++ )
      xprintf("  ");
     set_att( NormalColor );
     ClrShowArea( 0 );
  }

  return 0;

}

static void putstr_inp( u_char *p )
{
/*
  if ( CurInMethod == 9 ) {

     if ( strlen( p ) == 2 && isBig5( *p, *p + 1 ) ) {

      number_of_boshiamy_word_count++;
      number_of_boshiamy_key_count += ci;

     }

  }
*/
  if ( strlen( p ) != 2 )
     putstr( p );
  else
     sendkey_b5( p );

  ClrIn();
  ClrSelArea();
  ClrInArea();
}

/* return the keys of inmdno input method to generate the Chinese
   character ch, return keys in out  (ch is a two-bytes char)
   inmdn0 = 14, use the sinmd default one */
void b52key( int inmdno, u_char *ch, u_char *out )
{
  int k[11], slen;
  int i;
  char *kname;
  char uuu[MAX_PATH_LENGTH];
  u_long kkk;
  u_short ofs, ofs1;
  INMD *inp;
  ITEM it;
  static int last_inmdno = 0;

  if( inmdno == 14 )
     inp = &showinmd;
  else
     inp = &inmd[inmdno];

  strcpy( uuu, tabfname[inmdno] );
  strcat( uuu, ".rev" );

  if ( !inp->fp ) {
     if ( ( inp->fp = fopen( uuu, "r" ) ) == NULL ) {
      out[0] = 0;
      return ;
     }
  }

  if( last_inmdno != inmdno ) {
     fseek( inp->fp, 0, 0);
     fread( revidx, 2, 256, inp->fp );
  }

  kname=inp->keyname;

  *out = 0;
  ofs  = revidx[ch[0]    ];
  ofs1 = revidx[ch[0] + 1];

  fseek( inp->fp, ofs * sizeof( ITEM ) + 256 * 2, 0 );

  slen = 0;

  while ( ofs < ofs1 ) {

     if( fread( &it, 1, sizeof( ITEM ), inp->fp ) != sizeof( ITEM ) )
      break;

     ofs++;

     if( it.ch[1]  > ch[1] )
      break;

     if( it.ch[1] != ch[1] || it.ch[0] != ch[0] )
      continue;

     printf("Key1 %c%c%c%c\n",it.key1[0], it.key1[1], it.key1[2], 
            it.key1[3]);

     kkk = CONVT( it.key1 );
     
     printf("kkk Key %ld \n", kkk);

     for( i = 1; i <= 5; i++ )
      k[i] = ( kkk >> ( 30 - 6 * i ) ) & 0x3f;

     kkk = CONVT( it.key2 );

     for( i = 6; i <= 10; i++ )
      k[i] = ( kkk >> ( 60 - 6 * i ) ) & 0x3f;

     for( i = 1; i <= 10; i++ ) {

      if ( k[i] ) {

         out[slen++] = kname[   k[i]<<1       ];
         out[slen++] = kname[ ( k[i]<<1 ) + 1 ];

      } else
         break;

     } /* End for(i=1;i<=10;i++) */

     slen++;

     if ( slen > 90 ) {
      out[slen++] = 0;
      break;
     }

  } /* End  while ( ofs < ofs1 )  */

  out[slen++] = 0;

  printf("%c%c ==== %s", ch[0], ch[1], out);
  last_inmdno = inmdno;
}


#define swap( a , b ) { tt = a; a = b; b = tt; }

static u_long vmask[]=
{
  /* 0x3f 就是二进位的 00111111 */

   0        ,
   0x3f<<24   ,
 ( 0x3f<<24 ) | ( 0x3f<<18 ) ,
 ( 0x3f<<24 ) | ( 0x3f<<18 ) | ( 0x3f<<12 ) ,
 ( 0x3f<<24 ) | ( 0x3f<<18 ) | ( 0x3f<<12 ) | ( 0x3f<<6 ) ,
 ( 0x3f<<24 ) | ( 0x3f<<18 ) | ( 0x3f<<12 ) | ( 0x3f<<6 ) | 0x3f

};


int qcmp_b5( const void *a, const void *b )
{
  return strcmp( (u_char *)a, (u_char *)b );
}


void wildcard()
{
  int i,t,match, wild_ofs = 0;
  u_long kk1, kk2;
  char input[11], block[11];
  int found = 0;

  ClrSelArea();

  bzero( seltab, sizeof( seltab ) );
  defsel = 0;
  gotoxy( 1, MROW - 2 );
  t=0;

  for( i = 0; i < 10; i++ ) {

     if( inch[i] )
      input[i] = cur_inmd->keyvvv[inch[i]];
     else
      break;

  }

  input[i]  = 0;
  block[10] = 0;

  do {

     kk1 = CONVT( cur_inmd->tbl[t].key1 );
     kk2 = CONVT( cur_inmd->tbl[t].key2 );

     for( i = 0; i < 5; i++ ) {

      if( ( kk1 >> ( 24 - 6 * i ) ) & 0x3f )
        block[i] = cur_inmd->keyvvv[( kk1 >> ( 24 - 6 * i ) ) & 0x3f];
      else
        break;
     }

     block[i]=0;

     if( i == 5 ) {

      for( i = 0; i < 5; i++ ) {

        if( ( kk2 >> ( 24 - 6 * i ) ) & 0x3f )
          block[5 + i] = cur_inmd->keyvvv[( kk2 >> ( 24 - 6 * i ) ) & 0x3f];
        else
          break;

      }

      block[ 5 + i ] = 0;

     }

     match = MyPos( input, block, 0, 0 );

     if ( match && defsel < 10 ) {

      if ( wild_ofs >= wild_page ) {

        if( cur_inmd->NoBosh )
          xprintf( "%d%c%c", ( defsel + 1 ) % 10,
                  cur_inmd->tbl[t].ch[0],
                  cur_inmd->tbl[t].ch[1]  );
        else
        if ( !defsel )
          xprintf( " %c%c",  cur_inmd->tbl[t].ch[0],
                  cur_inmd->tbl[t].ch[1]  );
        else
          xprintf( "%d%c%c", defsel%10,
                  cur_inmd->tbl[t].ch[0],
                  cur_inmd->tbl[t].ch[1]  );

        cursor_x++;

        b2cpy( seltab[defsel++], cur_inmd->tbl[t].ch );

      } else wild_ofs++;

      found = 1;
     } else
     if ( match && defsel == 10 ) {

      if ( defsel == 10 )
        wild_next_page = 1;

      gotoxy( 42, 0 );

      if( wild_page == 0 && wild_next_page )
        xprintf( ">" );

      if( wild_page > 0 && wild_next_page ) {

        gotoxy( 41, 0 );
        xprintf( "<\\>" );

      } else
      if ( !wild_next_page )
         xprintf( "<" );

      break;
     }

     t++;

  } /* end do */
  while( t < cur_inmd->DefChars && defsel <= 10 );

  if( wild_next_page && wild_page > 0 && defsel <= 9 ) {
     gotoxy( 42, 0 );
     xprintf( "<" );
  }

  if ( !found )
     bell( 1 );

} /* end function wildcard() */


static char *is_selkey( int key )
{
      return strchr( cur_inmd->selkey, key );
}


static void load_phr( int j, char *tt )
{

  FILE *fp = cur_inmd->fphr;
  int ofs[2], len;
  int phrno = ( (int)( cur_inmd->tbl[j].ch[0] ) << 8 )| cur_inmd->tbl[j].ch[1];

  fseek( fp, ( phrno + 1 ) * 4, SEEK_SET );
  fread( ofs, 4, 2, fp );
  len = ofs[1] - ofs[0];

  if ( len > 128 || len <= 0 ) {
     error( "phrase error %d\n" , len );
     strcpy( tt, "err" );
     return;
  }

  ofs[0] += ( cur_inmd->phrnum + 1 ) * 4;
   /* Add the index area length */
  fseek( fp, ofs[0], SEEK_SET );
  fread( tt, 1, len, fp );
  tt[len] = 0;

}

int feedkey( int key )
{
  int i, j;
  int inkey = 0;
  int exa_match;
  char *iselkey = (char *)0;
  static int s1, e1;
  static u_long val1, val2;

/*
  ClrShowArea( 1 );
*/

  switch ( key ) {

     case XK_BackSpace:
#if   DELETE_K
     case XK_Delete:
#endif
      gotoxy( 40, 0 );
      xprintf("      ");
      m_pg_mode = 0;
      more_pg  = 0;
      last_idx = 0;

      if ( ci == 0 )
         return 0;

      if ( ci >  0 )
         inch[--ci]=0;

      if( cin > 0 )
         inch_box[--cin] = 0;

      for( i = 0; i < 10; i++ )
         if (inch[i]>60) {
            DispInArea();
            wild_mode=1;
            wild_page=0;
            wildcard();
            return 1;
         }

      wild_mode = spc_pressed = 0;

      if ( ci == 1 && cur_inmd->use_quick ) {

         int i;

         bzero( seltab, sizeof( seltab ) );

         for( i = 0; i < 10; i++ )
            memcpy( seltab[i], &cur_inmd->quick1[inch[0]-1][i][0], 2 );

         defsel = 10;
         DispInArea();
         return Disp_opt(s1, key);
      }

      break;

     case XK_Escape:

      if (ci) {
         ClrSelArea();
         ClrInArea();
         ClrIn();
         return 1;
      }
      else
         return 0;

     case '<':
     case '-':
     case ',':
     case '[':
      if ( wild_mode ) {

         if ( wild_page >= 10 )
            wild_page -= 10;
         wildcard();

         return 1;

      } else
        if ( more_pg ) {

         if ( now_idx > s1)
            j = now_idx-cur_inmd->M_DUP_SEL;
         else
            j = s1;

         goto next_pg;

        }
      else
         return 0;

     case '>':
     case ']':
     case '.':
     case '=':
      if ( wild_mode ) {

         if (defsel == 10)
            wild_page += 10;
         else
            wild_page =  0;

         wildcard();
         return 1;

        } else
        if ( more_pg ) {

         j = pg_idx;
         goto next_pg;

      }
      else
         return 0;

     case ' ':
/*
      if( CurInMethod == 9 )
         if ( verify_boshiamy( &val1, &val2 ) == 1 )
            return 1;
*/
      if ( ci == 0 ) {

         if ( last_full && cur_inmd->last_full == 1 ) {
            last_full = 0;
            return 1;
         }

         ClrSelArea();
         return 0;

      }

      if ( wild_mode && seltab[0][0] ) {

         if ( seltab[1][0] )
            bell( 2 );

         putstr_inp( seltab[0] );
         return 1;

      }

      for( i = 0; i < 10; i++ )
         if ( inch[i] > 60 ) {
            wild_page = 0;
            wild_mode = 1;
            wildcard();
            return 1;
         }


      if ( cur_inmd->NoBosh ) {

         if ( seltab[sel1st_i][0] ) {

            if ( seltab[1][0] )
               bell( 2 );

            putstr_inp( (u_char *)&seltab[sel1st_i] ); 
            return 1;

         }

         if ( spc_pressed == 1 || ci == cur_inmd->MaxPress ) {

            if ( seltab[1][0] )
               bell( 2 );

            putstr_inp( (u_char *)&seltab[0] );
            return 1;

         } else
         if ( ci == 1 && cur_inmd->use_quick ) {

            if ( seltab[1][0] )
               bell( 2 );

            putstr_inp( (u_char *)&seltab[0] );
            return 1;
         }
      }
      else {

         if ( seltab[sel1st_i][0] ) {

            if ( seltab[1][0] )
               bell( 2 );

            putstr_inp( (u_char *)&seltab[sel1st_i] );
            return 1;

         }

         if ( seltab[0][0] ) {

            if ( seltab[1][0] )
               bell( 2 );

            putstr_inp( (u_char *)&seltab[0] );
            return 1;
         }

      }

        if (ci && clear_wrong) {
           ClrSelArea();
           ClrInArea();
           ClrIn();
         bell( 1 );
           return 1;
        }

      last_full   = 0;
      spc_pressed = 1;
      break;

     case '?':
     case '*':

      if(wildmode) {

         ClrSelArea();

         if ( ci< cur_inmd->MaxPress ) {

            inkey = cur_inmd->keymap[key];
            inch[ci++] = inkey;
            DispInArea();
            wild_page = 0;
            wild_mode = 1;
            wildcard();
            return 1;

         }

      }

      return 0;

     default:

      if ( key >= XK_KP_0 && key <= XK_KP_9 )
         key -= XK_KP_0 - '0';

      if ( key < 32 || key > 0x7e ) {

         if ( seltab[sel1st_i][0] ) 
            putstr_inp( seltab[sel1st_i] );  

         return 0;

      }

      if( cin < cur_inmd->MaxPress )
         inch_box[cin++] = key;

      inkey   = cur_inmd->keymap[key];
      iselkey = is_selkey( key );

        if( cur_inmd->NoBosh ) {

         if( ( inkey >= 1 && inkey < 60 ) && !iselkey && spc_pressed ) {

            putstr_inp( (u_char *)&seltab[0] );

            if( cin < cur_inmd->MaxPress )
            inch_box[cin++] = key;

            inkey   = cur_inmd->keymap[key];
            iselkey = is_selkey( key );

         }

      }

      if ( iselkey && !ci && !( inkey >= 1 && inkey < 60 ) )
         return 0;

      if ( !iselkey && seltab[sel1st_i][0] && key!=8 && !wild_mode )
         putstr_inp( seltab[sel1st_i] );  

      if ( inkey>=1 && ci< cur_inmd->MaxPress ) {
            inch[ci++] = inkey;
            last_full  = 0;
            if ( ci == 1 && cur_inmd->use_quick ) {
                  int i;
                  for( i = 0; i < 10; i++ )
                  b2cpy( seltab[i], &cur_inmd->quick1[inkey-1][i][0] );
                  defsel = 10;
                  DispInArea();
                  return Disp_opt( s1, key );
            }
      }

      if ( inkey )
         for( i = 0; i < 10; i++ )
            if ( inch[i] > 60 ) {
                  DispInArea();
                  wild_mode = 1;
                  wild_page = 0; 
                  wildcard();
                  return 1;
            }

/*    if ( iselkey && CurInMethod == 8 && inch[0] == 23 && ci == 3 )
         goto YYYY;
*/ /* 上面那一段程式码我也不知道是干什麽用的,所以把它变成注解,
      如果以後知道的话再恢复 */

      if ( !inkey && iselkey && defsel )
         goto YYYY;

      if ( !inkey && !iselkey )
         return 0;

  } /* switch */

  if ( ci == 0 ) {
     ClrSelArea();
     ClrInArea();
     ClrIn();
     return 1;
  }

  DispInArea();

  val1 = inch[4]|(inch[3]<<6)|(inch[2]<<12)|(inch[1]<<18)|(inch[0]<<24);
  val2 = inch[9]|(inch[8]<<6)|(inch[7]<<12)|(inch[6]<<18)|(inch[5]<<24);

  if ( !last_idx ) {
     s1 = cur_inmd->idx1[inch[0]];
  } else
     s1 = last_idx;

  e1 = cur_inmd->idx1[inch[0]+1];

  while (
      ( ( ( CONVT( cur_inmd->tbl[s1].key1 ) & vmask[ci] )   != val1
            && CONVT( cur_inmd->tbl[s1].key1 )            <  val1 )
      ||
      ( ( CONVT( cur_inmd->tbl[s1].key2 ) & vmask[ci-5] ) != val2
          && CONVT( cur_inmd->tbl[s1].key2 )              <  val2 ) )
      &&  s1 < e1 )
    s1++;

  last_idx = s1;

  if ( iselkey && defsel &&
       (    ( CONVT( cur_inmd->tbl[s1].key1 ) & vmask[ci] )  !=val1
       || ( CONVT( cur_inmd->tbl[s1].key2 ) & vmask[ci-5] ) != val2
       || ( wild_mode && defsel )
       || ( ci == cur_inmd->MaxPress || spc_pressed )
        )
      ) {
YYYY:
     if ( ( iselkey || wild_mode ) && defsel ) {

      int vv = iselkey-cur_inmd->selkey;

      if ( vv < 0 )
         vv = 9;

      if ( !cur_inmd->NoBosh ) {
         if ( seltab[ vv ][0] )
            putstr_inp( seltab[ vv ] );
         return 1;
      }
      else {
         if ( seltab[vv][0] )
            putstr_inp( seltab[vv] );
         return 1;
      }

     }

     if ( iselkey && inkey == 0 && !defsel )
      return 0;

     bell( 1 );

     if ( ci > 0 )
      inch[--ci] = 0;

     last_idx = 0;
     DispInArea();
     return 1;

  }

/*  if ( CurInMethod == 8 && CONVT( cur_inmd->tbl[s1].key1) == val1
      && CONVT( cur_inmd->tbl[s1].key2 ) == val2 && iselkey ) {
            spc_pressed = 1;
      }
*/ /* 上面这一段在干什麽我并不是很清楚,先将它变成注解,
      以後如果知道用处了再加回来 */

  j = s1;

  if ( ( ci < cur_inmd->MaxPress && !spc_pressed )
       || ( ci  == cur_inmd->MaxPress && !cur_inmd->NoBosh && !spc_pressed
&& cur_inmd->last_full == 2 )
       || ( cin < cur_inmd->MaxPress && !spc_pressed ) ) {

     defsel = 0;
     bzero( seltab, sizeof( seltab ) );

     if ( defsel ) SORTFUNC( seltab, defsel, MAX_CIN_PHR, qcmp_b5 );
     exa_match = defsel - 1;

     if ( !cur_inmd->NoBosh )
      while( CONVT( cur_inmd->tbl[j].key1 ) == val1 &&
            CONVT( cur_inmd->tbl[j].key2 ) == val2 &&
            defsel < cur_inmd->M_DUP_SEL && j < e1 ) {
            if ( cur_inmd->tbl[j].ch[0] < 0x80 )
               load_phr( j++, seltab[defsel++] );
            else
               b2cpy( &seltab[defsel++], cur_inmd->tbl[j++]. ch );
      }

     if ( defsel < cur_inmd->M_DUP_SEL && cin > 0 ) {

      int s_h, e_h;

      pg_idx = 0;
      inch_box[cin] = 0;
      s_h = cur_inmd->kmap[inch_box[0]];
      e_h = cur_inmd->kmap[inch_box[0]+1];

      for( i = s_h; i < e_h; i++ )
         if ( !strcmp( &ph[cur_inmd->idx[i]], inch_box ) )
            break;

      pg_idx = i;
      while( i < e_h && !strcmp( &ph[cur_inmd->idx[i]], inch_box ) ) {
         memcpy( &seltab[defsel++],
            &ph[cur_inmd->idx[i]] + strlen( &ph[cur_inmd->idx[i]]) + 1,
            strlen( &ph[cur_inmd->idx[i]] +
              strlen( &ph[cur_inmd->idx[i]] ) + 1 ) );
         i++;
      }
     }

     if ( j < e1 && CONVT( cur_inmd->tbl[j].key1 ) == val1 &&
        CONVT( cur_inmd->tbl[j].key2 ) == val2 &&
        defsel == cur_inmd->M_DUP_SEL ) {

      pg_idx = j;
      more_pg = 1;
      last_page = 0;
      m_pg_mode = 1;
     } else
     if ( m_pg_mode ) {
      pg_idx = s1;
      last_page = 1;
      more_pg = 1;
     }

     now_idx = s1;

     if( defsel == 0 && spc_pressed )
      bell( 1 );

} else {
next_pg:
     defsel = more_pg = 0;
     now_idx = j;
     bzero( seltab, sizeof( seltab ) );

     while( CONVT( cur_inmd->tbl[j].key1 ) == val1 &&
            CONVT( cur_inmd->tbl[j].key2 ) == val2 &&
            defsel < cur_inmd->M_DUP_SEL && j < e1 ) {

      if ( cur_inmd->tbl[j].ch[0] < 0x80 )
         load_phr( j++, seltab[defsel++] );
      else
         b2cpy( &seltab[defsel++], cur_inmd->tbl[j++].ch );

     }

     if ( defsel < cur_inmd->M_DUP_SEL && cin > 0 ) {

      int s_h, e_h;

      pg_idx = 0;
      inch_box[cin] = 0;
      s_h = cur_inmd->kmap[inch_box[0]];
      e_h = cur_inmd->kmap[inch_box[0] + 1];

      for( i = s_h; i < e_h; i++ )
         if ( !strcmp( &ph[cur_inmd->idx[i]], inch_box ) )
            break;

      pg_idx = i;

      while( i < e_h && !strcmp( &ph[cur_inmd->idx[i]], inch_box ) ) {
         memcpy( &seltab[defsel++],
               &ph[cur_inmd->idx[i]] + strlen( &ph[cur_inmd->idx[i]] ) + 1,
               strlen( &ph[cur_inmd->idx[i]] +
                     strlen( &ph[cur_inmd->idx[i]] ) + 1 ) );
         i++;
      }
     }

     if ( j < e1 && CONVT( cur_inmd->tbl[j].key1 ) == val1 &&
        CONVT( cur_inmd->tbl[j].key2 ) == val2 &&
        defsel == cur_inmd->M_DUP_SEL ) {

      pg_idx    = j;
      more_pg   = 1;
      last_page = 0;
      m_pg_mode = 1;

     } else
     if ( m_pg_mode ) {

      pg_idx    = s1;
      more_pg   = 1;
      last_page = 1;

     }

     if ( ci == cur_inmd->MaxPress && !spc_pressed && defsel == 1 ) {
      if ( cur_inmd->last_full == 0 || cur_inmd->last_full == 1 )
         putstr_inp( (u_char *)&seltab[0] );
      if ( cur_inmd->last_full == 1 )
         last_full = 1;
      else last_full = 0;
      return 1; 
     }

     if ( ci == cur_inmd->MaxPress && more_pg && spc_pressed ) {
      putstr_inp( (u_char *)&seltab[0] );
      return 0;
     }

     if ( defsel == 1 && !more_pg ) {
      if (ci == cur_inmd->MaxPress )
         last_full = 1;
      putstr_inp( seltab[0] );
      return 1;
     } else
     if ( !defsel ) {
      bell( 1 );
      DispInArea();
      spc_pressed = 0;
      return Disp_opt( s1, key );
     } else
     if ( !more_pg )
      bell( 2 );

     if ( !cur_inmd->NoBosh && !more_pg && spc_pressed ) {
      putstr_inp( (u_char *)&seltab[0] );
      return 0;
     }

  }

  if ( cur_inmd->NoBosh && spc_pressed )
     while (   CONVT( cur_inmd->tbl[j].key1 ) == val1
            && CONVT( cur_inmd->tbl[j].key2 ) == val2
            && defsel < 10 ) {
        if ( cur_inmd->tbl[j].ch[0] >= 0x80 )
        b2cpy( seltab[defsel++], cur_inmd->tbl[j].ch );
        j++;
     }


  return Disp_opt( s1, key );

}

static int Disp_opt( int s1, int key )
{

  int i;

  ClrSelArea();
  sel1st_i = 15;
  gotoxy( 0, 0 );

  if ( cur_inmd->sel1st ) {

     int k;

     for( i = cur_inmd->M_DUP_SEL ; i >= 0 ; i-- ) {

      if ( ( cur_inmd->NoBosh && ( spc_pressed || ci == cur_inmd->MaxPress ) )            || ( !cur_inmd->NoBosh ) ) {

         for( k = 0; cur_inmd->sel1st[k]; k += 2 )
            if ( !memcmp( &cur_inmd->sel1st[k], seltab[i], 2 ) ) {

               sel1st_i = i;
               break;

            }

         } /* end if( (cur_inmd .......) */
     }

     if ( sel1st_i == 15 && !i && !more_pg ) {

      sel1st_i = i;

     }

     if ( ( spc_pressed || ci == cur_inmd->MaxPress )&& !i && !more_pg ) {

      sel1st_i = i;

     }

  }

  for( i = 0; i <= cur_inmd->M_DUP_SEL; i++ ) {

     if ( !seltab[i][0] ) break;

/*
     if ( !cur_inmd->NoBosh ) { /* 如果使用呒虾米的「先上字」模式 */
/*
      if ( i == sel1st_i && !more_pg )
         set_att( InAreaColor );

      if ( ( i + 1 ) % cur_inmd->M_DUP_SEL == 1 )
         xprintf( " " );
      else
         xprintf( "%c", cur_inmd->selkey[i % cur_inmd->M_DUP_SEL-1] );

     }
     else  */ {
     
      if ( i == sel1st_i && !more_pg )
         set_att( InAreaColor );

      if ( i % 10 == 0 )
         xprintf( " " );

      xprintf( "%c", cur_inmd->selkey[i % 10] );

     }

     set_att( NormalColor );
     xprintf( "%s", seltab[i] );
     cursor_x += 1;

  }

  if ( more_pg ) {

     gotoxy( 41, 0 );

     if( now_idx == s1 )
      xprintf( ">" );
     else
     if ( last_page )
      xprintf( "<" );
     else {
      gotoxy( 40, 0 );
      xprintf( "<\\>" );
     }
  }

  if ( strchr( cur_inmd->endkey,key ) && ci < cur_inmd->MaxPress )
     feedkey( ' ' );

  return 1;

}

Generated by  Doxygen 1.6.0   Back to index