/* This file is part of the origami distribution. (Amiga Port)
 *
 * Source code written by Thomas Hadig in September 1991
 * Version : 1.6.92.1, February 1994
 * (C) 1991-94 by Thomas Hadig
 * may be distributed unchanged ! (see copyright notes)
 */

/*{{{}}}*/
/*{{{  #includes*/
/*{{{  standard includes*/
#include <exec/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <signal.h>
#include <limits.h>
/*}}}  */
/*{{{  amiga system includes*/
#include <intuition/intuition.h>
#include <intuition/intuitionbase.h>
#include <exec/io.h>
#include <devices/timer.h>
#include <devices/inputevent.h>
#include <workbench/workbench.h>
#include <workbench/startup.h>
#include <dos.h>
/*}}}  */
/*{{{  amiga prototype includes*/
#include <clib/alib_protos.h>
#include <clib/exec_protos.h>
#include <clib/intuition_protos.h>
#include <clib/console_protos.h>
#include <clib/icon_protos.h>
#include <clib/dos_protos.h>
#include <clib/graphics_protos.h>
/*}}}  */

#define KEYBOARD_C
#define I_SIGNALS_C
#define I_PROMPT_C
#define I_GETTK_C
#define I_KEYTAB_C
#define I_MAIN_C
#define I_FOLDING_C
#define I_VIRTUAL_C
#define I_SCREEN_C
#define I_GETMSG_C
#define I_INIT_C
#define I_MESSAGES_C
#define I_LOOP_C
#define I_BUFFLOOP_C
#define I_DISPLAY_C
#define I_STRING_C

#include <origami/origami.h>
#include <h/envvar_str.h>

#include <graphics/gfxbase.h>

#include <sprof.h>
/*}}}  */

/*{{{  variables*/
/*{{{  get key global variables*/
public TOKEN buffer_keys[buffer_keys_max];
public int   key_buffer_max = 0;
/*}}}  */
public boolean echo_active, echo_disabled=False, eight_bits=True;
private FILE *kbd_p=(FILE *)0;
/*}}}  */

/*{{{  enable and switch echo*/
/*{{{  enable_echo*/
public void enable_echo(boolean const yes)
 { echo_active=(!echo_disabled && yes); }
/*}}}  */
/*{{{  switch_echo*/
public void switch_echo(boolean const on)
 { echo_disabled=!(echo_active=on); }
/*}}}  */
/*}}}  */
/*{{{  enable, disable abort*/
/*{{{  enable_abort*/
public void enable_abort(void) {}
/*}}}  */
/*{{{  disable_abort*/
public void disable_abort(void) { signal(SIGINT, SIG_IGN); }
/*}}}  */
/*}}}  */
/*{{{  init and reset keyboard*/
/*{{{  init_keyboard*/
public void init_keyboard(void)
 {
  disable_abort();
  enable_echo(!echo_disabled);
 }
/*}}}  */
/*{{{  reset_keyboard*/
public void reset_keyboard(void) {}
/*}}}  */
/*}}}  */
/*{{{  get_key procedures*/
/*{{{  MakeRawKey*/
private TOKEN MakeRawKey (USHORT code, USHORT quali, unsigned char init)
 {
  unsigned char b = 65;

  if (code==general_abort_key) code = PSEUDO_ABORT_KEY;
  buffer_keys[key_buffer_max++] = init;
  if (quali & 0x0003) b++; /* SHIFT */
  if (quali & 0x0008) b+=2; /* Control */
  if (quali & 0x0030) b+=4; /* ALT */
  if (quali & 0x0040) b+=8; /* left Amiga */
  if (quali & 0x0080) b+=16; /* right Amiga */
  buffer_keys[key_buffer_max++] = b;
  buffer_keys[key_buffer_max++] = code;
  return (TOKEN)CSI;
 }
/*}}}  */
/*{{{  copy_tokens*/
private TOKEN copy_tokens(int o,unsigned char *buf1)
 {
  int i;

  for (i=0; i<o;buffer_keys[key_buffer_max+i]=(TOKEN)buf1[++i]);
  key_buffer_max += o-1;
  return (TOKEN)buf1[0];
 }
/*}}}  */
/*{{{  inconify*/
#ifdef ICONIFY
private void iconify (SHORT ileft,SHORT itop,SHORT iwidth,SHORT iheight,
  struct IntuiMessage **m)
 {
  struct IntuiMessage *mg;
  boolean stop = FALSE;

  ReplyMsg ((struct Message *)*m);
  *m=0;
  if (bd.f.real_head!=bd.f.real_tail)
    strcpy(window_name,get_data(bd.f.real_tail));
  /*{{{  switch menu line off*/
#  ifdef MENU
  if (menu_on==True) ClearMenuStrip (wind);
#  endif
  /*}}}  */
  /*{{{  make small*/
  SetWindowTitles (wind,window_name,(char *)-1);
  ChangeWindowBox (wind, 0,0, 400, 2+off_y);
  /*}}}  */
  /*{{{  wait for re-activation*/
  do
   {
    PROFILE_OFF();
    Wait (1L << wind->UserPort->mp_SigBit);
    PROFILE_ON();
    while ((stop==False)&&
      (mg = (struct IntuiMessage *)GetMsg (wind->UserPort)))
     {
      if ((mg->Class==GADGETDOWN)|| (mg->Class==CLOSEWINDOW)) stop = True;
      ReplyMsg ((struct Message *) mg);
     }
   } while (stop==False);
  /*}}}  */
  /*{{{  make large*/
  strcpy (window_name,"Origami");
  SetWindowTitles (wind,window_name,(char *)-1);
  ChangeWindowBox (wind, ileft, itop, iwidth, iheight);
  /*{{{  Wait for resize completion*/
  do
   {
    PROFILE_OFF();
    Wait (1L << wind->UserPort->mp_SigBit);
    PROFILE_ON();
    while ((stop==True)&&
      (mg = (struct IntuiMessage *)GetMsg (wind->UserPort)))
     {
      if (mg->Class==IDCMP_CHANGEWINDOW) stop = False;
      ReplyMsg ((struct Message *) mg);
     }
   } while (stop==True);
  /*}}}  */
  /*}}}  */
  /*{{{  switch menu line on*/
#  ifdef MENU
  if (menu_on==True) SetMenuStrip (wind,menu_root);
#  endif
  /*}}}  */
 }
#endif
/*}}}  */
/*{{{  cut and paste things*/
#ifdef CUTPASTE
/*{{{  includes*/
#include <libraries/iffparse.h>
#include <clib/iffparse_protos.h>
/*}}}  */

/*{{{  defines*/
#ifndef ID_CHRS
#define  ID_CHRS	MAKE_ID('C','H','R','S')
#endif
#ifndef ID_FTXT
#define  ID_FTXT	MAKE_ID('F','T','X','T')
#endif
/*}}}  */
/*{{{  variables*/
private struct cupa *cupa_root=(struct cupa *)0;
/*}}}  */

/*{{{  get_from_cutpaste*/
private void get_from_cutpaste (void)
 {
  int error;
  struct ContextNode *cn;
  struct IFFHandle   *iff;

  if (!IFFParseBase) return;
  if (!(iff=AllocIFF())) return;
  if (!(iff->iff_Stream = (ULONG) OpenClipboard (PRIMARY_CLIP))) goto err1;
  InitIFFasClip (iff);
  if (OpenIFF (iff,IFFF_READ)) goto err2;
  if (StopChunk (iff, ID_FTXT, ID_CHRS)) goto err3;
  while (1)
   /*{{{  handle all chunks*/
   {
    if (error = ParseIFF(iff,IFFPARSE_SCAN))
     /*{{{  error or no more CHRS chunk*/
     {
      if (error==IFFERR_EOC) continue;
      break;
     }
     /*}}}  */
    cn=CurrentChunk (iff);
    if (cn && (cn->cn_Type==ID_FTXT) && (cn->cn_ID==ID_CHRS))
     /*{{{  handle one chunk*/
     {
      struct cupa *cp2, *cp=cupa_root;
      int len;

      do
       /*{{{  read and add to list*/
       {
        if (!(cp2 = (struct cupa *)malloc (sizeof (struct cupa))))
          goto err3;
        cp2->Next = (struct cupa *)0;
        cp2->cur_pos = 0;
        if (len = ReadChunkBytes(iff,&(cp2->text[0]),CUPA_TEXT_LEN-1))
         /*{{{  store bytes*/
         {
          cp2->text[len]=0;
          if (cp)
           /*{{{  add cp2 at end of the list*/
           {
            while (cp->Next) cp=cp->Next;
            cp->Next = cp2;
           }
           /*}}}  */
          else cp=cupa_root=cp2;
         }
         /*}}}  */
        else free (cp2);
       /*}}}  */
       } while (len>0);
     }
     /*}}}  */
   }
   /*}}}  */
err3: CloseIFF (iff);
err2: CloseClipboard ((struct ClipboardHandle *)iff->iff_Stream);
err1: FreeIFF(iff);
 }
/*}}}  */
/*{{{  put_to_cutpaste*/
private void put_to_cutpaste (struct IntuiMessage *mg)
 {
  int begx,begy,stop=0,endx,endy;
  struct IFFHandle   *iff;

  begx = (mg->MouseX-Off_X)/mul_x+1;
  begy = (mg->MouseY-off_y-1)/mul_y+1;
  /*{{{  wait for release on the end-point*/
  do
   /*{{{  repeat till mousebutton has been release*/
   {
    PROFILE_OFF();
    Wait (1L << wind->UserPort->mp_SigBit);
    PROFILE_ON();
    while ((!stop)&&(mg = (struct IntuiMessage *)GetMsg (wind->UserPort)))
     /*{{{  handle all messages*/
     {
      if ((mg->Class==IDCMP_MOUSEBUTTONS)&&
          ((mg->Code & SELECTUP) == (SELECTUP)))
       /*{{{  has the right mousebutton been released ??*/
       {
        if (mg->Qualifier & 0x80)
         /*{{{  right-amiga still pressed ?? yes*/
         {
          stop = 1;
          endx = (mg->MouseX-Off_X)/mul_x+1;
          endy = (mg->MouseY-off_y-1)/mul_y+1;
         }
         /*}}}  */
        else stop = -1;
       }
       /*}}}  */
      ReplyMsg ((struct Message *) mg);
     }
     /*}}}  */
   /*}}}  */
   } while (!stop);
  /*}}}  */
  if (stop==-1) return; /* right amiga was not pressed when released */
  if ((endy<begy)|| ((endy==begy)&&(endx<begx)))
   /*{{{  swap begin and end points, if end was before begin*/
   {
    int t;

    t=begy; begy=endy; endy=t;
    t=begx; begx=endx; endx=t;
   }
   /*}}}  */
  /*{{{  open clipboard device for writing*/
  if (!IFFParseBase) return;
  if (!(iff=AllocIFF())) return;
  if (!(iff->iff_Stream = (ULONG) OpenClipboard (PRIMARY_CLIP))) goto perr1;
  InitIFFasClip (iff);
  if (OpenIFF (iff,IFFF_WRITE)) goto perr2;
  if (PushChunk (iff,ID_FTXT, ID_FORM, IFFSIZE_UNKNOWN)) goto perr3;
  if (PushChunk (iff,0,ID_CHRS,IFFSIZE_UNKNOWN)) goto perr3;
   /*{{{  write selected area*/
   {
    char str[256],*p=str,ch;
    int sp;

    while (begy<=endy)
     /*{{{  handle all lines*/
     {
      sp=0;
      while (begx<= ((begy==endy) ? endx : screen.w))
       /*{{{  handle one line*/
       {
        if ((ch=cur_scr_char(begy,begx))==' ') sp++;
        else if (ch)
         /*{{{  handle non space characters*/
         {
          if (sp)
           {
            while (sp--)
             /*{{{  handle all leading spaces*/
             {
              *p++=' ';
              if (p-str>=256)
               /*{{{  Write, if buffer full*/
               {
                if (WriteChunkBytes (iff, str, 256)<0) goto perr3;
                p=str;
               }
               /*}}}  */
             }
             /*}}}  */
            sp=0;
           }
          *p++=ch;
          if (p-str==256)
           /*{{{  Write, if buffer full*/
           {
            if (WriteChunkBytes (iff, str, 256)<0) goto perr3;
            p=str;
           }
           /*}}}  */
         }
         /*}}}  */
        begx++;
       }
       /*}}}  */
      *p++='\n';
      if (p-str==256)
       /*{{{  Write, if buffer full*/
       {
        if (WriteChunkBytes (iff, str, 256)<0) goto perr3;
        p=str;
       }
       /*}}}  */
      begy++;
      begx=1;
     }
     /*}}}  */
    if (p!=str) if (WriteChunkBytes (iff, str, p-str)<0) goto perr3;
   }
   /*}}}  */
  if (PopChunk(iff)) goto perr3;
  PopChunk(iff);
  perr3: CloseIFF (iff);
  perr2: CloseClipboard ((struct ClipboardHandle *)iff->iff_Stream);
  perr1: FreeIFF(iff);
  /*}}}  */
 }
/*}}}  */
#endif
/*}}}  */

/*{{{  handle_message*/
private TOKEN handle_message (struct IntuiMessage *msg)
 {
  static struct InputEvent iev =
   /*{{{  initializer*/
   {
     (struct InputEvent *)0, 1, 0, 0, 0,0, 0,0
   };
   /*}}}  */
  TOKEN tok=0;

  switch (msg->Class)
   /*{{{  handle all classes*/
   {
    /*{{{  CloseWindow*/
    case CLOSEWINDOW:
      tok = O_QUIT;
      break;
    /*}}}  */
    /*{{{  RawKey*/
    case RAWKEY:
    {
      int o;
      unsigned char buf1[20];

      iev.ie_Code = msg->Code;
      iev.ie_Qualifier = msg->Qualifier;
      if ((!(msg->Code&0x80))&&((msg->Code&0x60)!=0x60))
       {
        if (o = RawKeyConvert(&iev,buf1,20,NULL))
         /*{{{  Vanilla key exists*/
         {
          if (msg->Qualifier&0x00FF) /* any qualifier */
           /*{{{  test if qualifier code is different to normal code*/
           {
            unsigned char buffer[20];

            iev.ie_Qualifier = 0;
            iev.ie_Code = msg->Code;
            if ((RawKeyConvert(&iev,buffer,20,NULL))==o)
             /*{{{  qualifier handled ?*/
             {
              buffer[o]=buf1[o]=0x00;
              if (!strcmp (buffer,buf1))
                tok = MakeRawKey (msg->Code,msg->Qualifier,
                  msg->Qualifier&IEQUALIFIER_NUMERICPAD ?
                    CSI_NUMBER_PAD : CSI_RAW_KEY);/*no*/
              else tok = copy_tokens(o,buf1);
             }
             /*}}}  */
            else tok = copy_tokens(o,buf1);
           }
           /*}}}  */
          else
           /*{{{  handle numberpad and keysequences*/
           {
            if (o>1) tok = copy_tokens(o,buf1);
            else if (msg->Qualifier & 0x0100) /* number pad */
              tok = MakeRawKey (msg->Code,msg->Qualifier,CSI_NUMBER_PAD);
            else tok = buf1[0];
           }
           /*}}}  */
         }
         /*}}}  */
        else tok = MakeRawKey (msg->Code,msg->Qualifier,CSI_RAW_KEY);
       }
      break;
     }
    /*}}}  */
    /*{{{  NewSize*/
    case NEWSIZE:
      win_changed = TRUE;
      tok=O_PROMPT;
      /*{{{  iconify if possible (else window is big enough)*/
#      ifdef ICONIFY
      if ((wind->Width<100)||(wind->Height<40))
        iconify (0,0,(short)639,height,&msg);
#      endif
      /*}}}  */
      break;
    /*}}}  */
    /*{{{  Menupick*/
#    if defined(MENU) | defined(MOUSY) | defined(CUTPASTE)
    /*{{{  MenuPick*/
    case MENUPICK:
      if (msg->Code!=MENUNULL)
       /*{{{  handle menu selects*/
       {
#       ifdef MENU
        /*{{{  handling menu-events*/
        tok = CSI;
        buffer_keys[key_buffer_max++] = CSI_MENU_PICK;
        buffer_keys[key_buffer_max++] = 48 + MENUNUM(msg->Code);
        buffer_keys[key_buffer_max++] = 48 + ITEMNUM(msg->Code);
        /*}}}  */
#       endif
       }
       /*}}}  */
      else
       /*{{{  handling mouse-events*/
       {
        int b=1; /* right mouse button, release */

        if (msg->Qualifier & 0x03) b+=5; /* Shift */
        else if (msg->Qualifier & 0x08) b+=10; /* Ctrl */
        else if (msg->Qualifier & 0x30) b+=15; /* Alt */
        else if (msg->Qualifier & 0x40) b+=20; /* left Amiga */
        else if (msg->Qualifier & 0x80) b+=25; /* right Amiga */
        /*{{{  test on cut & paste (here paste only)*/
#        ifdef CUTPASTE
        if (b==25+1) /* right Amiga menu up, no menu selected */
         {
          get_from_cutpaste ();
          tok = O_PROMPT;
          break;
         }
#        endif
        /*}}}  */
        /*{{{  make mousebutton event*/
#        ifdef MOUSY
        tok = handle_click ((msg->MouseX-Off_X)/mul_x+1,
          (msg->MouseY-off_y-1)/mul_y+1,b);
#        endif
        /*}}}  */
       }
       /*}}}  */
      break;
    /*}}}  */
#    endif
    /*}}}  */
    /*{{{  Iconify*/
#    ifdef ICONIFY
    /*{{{  Iconify*/
    case GADGETDOWN:
    {
      iconify (wind->LeftEdge, wind->TopEdge, wind->Width, wind->Height,&msg);
      win_changed = TRUE;
      tok=O_PROMPT;
      break;
    }
    /*}}}  */
#    endif
    /*}}}  */
    /*{{{  MouseButtons*/
#    if defined (MOUSY) | defined (CUTPASTE)
    /*{{{  MouseButtons*/
    case IDCMP_MOUSEBUTTONS:
     {
      int b = 0;

      if ((msg->Code & SELECTUP) == (SELECTDOWN)) b=3;
      /* b = 1  will be used in MENU PICK for RIGHT button */
      else if ((msg->Code & MIDDLEUP) == (MIDDLEUP)) b = 2;
      else if ((msg->Code & MIDDLEUP) == (MIDDLEDOWN)) b = 4;

      if (msg->Qualifier & 0x03) b+=5; /* Shift */
      else if (msg->Qualifier & 0x08) b+=10; /* Ctrl */
      else if (msg->Qualifier & 0x30) b+=15; /* Alt */
      else if (msg->Qualifier & 0x40) b+=20; /* left Amiga */
      else if (msg->Qualifier & 0x80) b+=25; /* right Amiga */
#    ifdef CUTPASTE
      if (b==25+3) put_to_cutpaste (msg); /*right amiga + selectdown */
      else
#    endif
        tok = handle_click ((msg->MouseX-Off_X)/mul_x+1,
          (msg->MouseY-off_y-1)/mul_y+1,b);
      break;
     }
    /*}}}  */
#    endif
    /*}}}  */
    /*{{{  Priority*/
#    ifdef PRIORITY
    /*{{{  ActiveWindow*/
    case ACTIVEWINDOW:
      SetTaskPri (FindTask(NULL),1);
      break;
    /*}}}  */
    /*{{{  InActiveWindow*/
    case INACTIVEWINDOW:
      SetTaskPri (FindTask(NULL),0);
      break;
    /*}}}  */
#    endif
    /*}}}  */
   }
   /*}}}  */
  if (msg) ReplyMsg ((struct Message *)msg);
  return tok;
 }
/*}}}  */
/*{{{  get_code*/
private TOKEN get_code (void)
 {
  TOKEN tok = 0;
  struct IntuiMessage *msg;

  /*{{{  keys there, that aren't used till now ?*/
  if (key_buffer_max)
   {
    tok = buffer_keys[0];
    memmove (buffer_keys,buffer_keys+1,key_buffer_max*sizeof(TOKEN));
    key_buffer_max--;
    return tok;
   }
  /*}}}  */
  /*{{{  if not : are there any cut&paste buffers ??*/
#  ifdef CUTPASTE
  if (cupa_root)
   {
    tok = cupa_root->text[cupa_root->cur_pos++];
    if (!cupa_root->text[cupa_root->cur_pos])
     {
      struct cupa *c=cupa_root;
      cupa_root = c->Next;
      free (c);
     }
    return tok;
   }
#  endif
  /*}}}  */
  while (!tok)
   /*{{{  get one token*/
   {
    /*{{{  from arexx ...*/
#    ifdef AREXX
    /*{{{  got signal from arexx ?*/
    if ((arexx==True)&&(_arexx)&&(_arexx->port)&&(!_arexx->tag)&&
        (_arexx->msg = GetARexxMsg ()))
     {
      if (handle_rexx())
       {
        _arexx->tag = 1;
        return O_PROMPT;
       }
     }
    else
    /*}}}  */
#    endif
    /*}}}  */
    /*{{{  got signal from timer.device ?*/
    if ((tr)&&(msg = (struct IntuiMessage *)GetMsg (mpp)))
     {
      if (msg->ExecMessage.mn_Node.ln_Type!= NT_REPLYMSG)
        ReplyMsg((struct Message *)msg);
      sig_alarm_reached(0);
      return O_PROMPT;
     }
    /*}}}  */
    /*{{{  got signal from intuition ?*/
    if ((msg = (struct IntuiMessage *)GetMsg (wind->UserPort)))
      tok = handle_message (msg);
    /*}}}  */
    else
     {
      PROFILE_OFF();
      Wait ((1L << wind->UserPort->mp_SigBit)|(my_signal)
      /*{{{  add arexx signal*/
#      ifdef AREXX
      |(_arexx->signal)
#      endif
      /*}}}  */
      );
      PROFILE_ON();
     }
   }
   /*}}}  */
  return tok;
 }
/*}}}  */
/*{{{  get_key*/
public TOKEN get_key (void)
 {
  oflush;
  ocl_msg("keyboard %d",ocl_var[var_key_count].v);
  for (;;)
   {
    /*{{{  variables*/
    int result= keytabcont;
    unsigned int ch=general_abort_key;
    int lg=0;
    /*}}}  */

    ocl_var[var_key_count].v+=1;
    /*{{{  scan a keyboard-sequence 'til token is complete*/
    while (result==keytabcont && !aborted)
     {
      /*{{{  try to read from keyboard*/
      if (scr_off) { ocl_msg ("read on scroff",0);
                     ori_abort (0);return (O_BREAK); }
      oflush;
      ch = get_code();
      /*}}}  */
      lg++;
      if (ch<256)
       {
        result=find_key(ch);
        /*{{{  echo-handling*/
        if (echo_active==True)
         {
          if (result==keytabcont)
           /*{{{  show sequence off pressed keys*/
           {
            if (lg==1)
             /*{{{  clear message line and move cursor*/
             {
              moveclreol(message_line,1);
              move_cursor_to(message_line,1);
             }
             /*}}}  */
            /*{{{  print the coding for ch*/
             {
              static unsigned char meta[]="M-";
              static unsigned char ctrl[]="C-x ";
              unsigned char *cp;

              /*{{{  cp=coding*/
              if (ch=='\033')
                cp=meta;
              else
               {
                cp=ctrl;
                if (ch>=(unsigned char)' ')
                  *(cp+=2)=ch;
                else
                  *(cp+2)=ctrl_decode[ch];
               }
              /*}}}  */
              prt_bin_text(0,LINELEN,FALSE,cp);
             }
            /*}}}  */
           }
           /*}}}  */
          else moveclreol(message_line,1);
         }
        /*}}}  */
       }
      else result = ch;
     }
    /*}}}  */
    if (aborted) return(O_BREAK);
    if (result!=keytabknb)
     {
      if (result!=keytabend) return (result);
      if (ch==general_abort_key)
       {
        ori_abort(0);
        return (O_BREAK);
       }
      if (lg==1) return ((TOKEN)ch);
     }
    if (knb_macro) call_number_macro(knb_macro);
    if (echo_active) message(get_msg(M_NOT_BOUND));
    return(O_PROMPT);
   }
 }
/*}}}  */
/*{{{  scan_abort_key*/
public void scan_abort_key (void)
 {
  struct IntuiMessage *msg;
  TOKEN tok;
  int old_key_buf;

  if (key_buffer_max>=buffer_keys_max-5) /* There are no keysequencese */
    return;                              /* longer than five codes */
  while ((!aborted)&&(key_buffer_max<buffer_keys_max-5))
   /*{{{  read all pressed keys, till buffer full or abort*/
   {
    if (! (msg = (struct IntuiMessage *)GetMsg (wind->UserPort))) break;
    old_key_buf = key_buffer_max++;  /* one place for tok */
    if ((unsigned int)(tok = handle_message (msg)) == general_abort_key)
     {
      key_buffer_max--;
      ori_abort(0);
     }
    else if (!tok) key_buffer_max--;
    else buffer_keys[old_key_buf]=tok;
   }
   /*}}}  */
 }
/*}}}  */
/*}}}  */
