home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 5 Edit / 05-Edit.zip / ehp14cs.zip / taste.c < prev    next >
C/C++ Source or Header  |  1994-12-13  |  26KB  |  661 lines

  1. /****************************************************************/
  2. /*                                                              */
  3. /*      MODUL:  taste.c                                         */
  4. /*                                                              */
  5. /*      FUNKTIONEN:                                             */
  6. /*              - lies_tasten (Tastenbelegunsfile einlesen)     */
  7. /*              - search_next (suche naechsten passenden Bef.)  */
  8. /*              - taste (Tastendruck auswerten)                 */
  9. /*              - newwgetch (Taste von Keyboard || Puffer lesen)*/
  10. /*              - exec_macro (Macro ausfuehren)                 */
  11. /*              - newgetstr (String mittels newgetch einlesen)  */
  12. /*              - get_comstr (Kommandostring einlesen)          */
  13. /*                                                              */
  14. /****************************************************************/
  15.  
  16. #ifdef OS2
  17. #define INCL_DOSSEMAPHORES
  18. #include <os2.h>
  19. #else
  20. #define _ANSI_SOURCE
  21. #endif
  22.  
  23. #include "defs.h"
  24. #include "keys.h"
  25. #include <ctype.h>
  26.  
  27. extern char helpflag;
  28. extern int ks_index;
  29. extern short int *keystack,*e_keystack;  /* puffer-pointer */
  30. extern short int mc_index;
  31. extern WINDOW *status;
  32. extern char clear_buff, /* aus main.c */
  33.         *tasten_inf; /* Name des Tastenbelegungsfiles aus main.c */
  34. extern int do_macro(),do_control(),do_newline(),(*funktion[])();  /* funktionsarray aus auswertung.c f. get_comstr */
  35. extern puff_typ macro[];
  36. #ifdef OS2
  37. extern HMTX sem_handle;
  38. #endif
  39.  
  40. /* *** globale Daten und Initialisierung *** */
  41. static short int eingabe[MAX_COMM_LEN]; /* Bisher eingelesene Zeichen          */
  42. static short int index=0,               /* Index in eingabe                    */
  43.          bef_index=0;           /* aktuelle moegliche Tastenkombination*/
  44. puff_typ  puff_feld[MACRO_NEST_DEPTH];  /* Macropuffer                         */
  45. comm_typ  *comm_feld;                   /* Tastenkombinationen                 */
  46. short int letter,                       /* Buchstabe, falls Befehl T_BUCHSTABE */
  47.       lastcode = -1,                /* Letzte Tastenkombination            */
  48.       newwgetch();
  49.  
  50. #ifndef OWN_CURSES
  51. /*****************************************************************************
  52. *
  53. *  Funktion       Warnton ausgeben (beep)
  54. *  --------
  55. *
  56. *  Beschreibung : Es wird ein CTRL-G ausgegeben, was einen Warnton erzeugt.
  57. *
  58. *****************************************************************************/
  59.  
  60. void beep()
  61. {
  62.    printf("");  /* Beep ausgeben */
  63. }
  64. #endif
  65.  
  66. /*****************************************************************************
  67. *
  68. *  Funktion       Tastenbelegungsfile einlesen (lies_tasten)
  69. *  --------
  70. *
  71. *  Beschreibung : Liest die Tastenbelegungsdatei in das Feld comm_feld ein.
  72. *
  73. *****************************************************************************/
  74.  
  75. void lies_tasten()
  76. {
  77.   /* *** interne Daten *** */
  78.   FILE               *f;     /* Filepointer fuer Tastenbelegungsdatei */
  79.   register short int i,      /* Zaehler fuer Kombinationsnummer       */
  80.              j;      /* Zaehler fuer Indexfeld                */
  81.   register int       n_info; /* Anzahl einzulesender Strings          */
  82.   short int          *index; /* Feld fuer Stringindices               */
  83.   char               *hilf,  /* Zeiger auf Hilfstring                 */
  84.              dummy [256]; /* Zum einlesen der Hilfstring      */
  85.  
  86.   if (!(f = fopen (tasten_inf,"rb"))) /* Tastebelegungsdatei oeffnen */
  87.   {
  88.     print_stat(PROMPT_KEYREAD);
  89.     wart_ret();
  90.     ende(1, TRUE);
  91.   }
  92.   if(fread(&mc_index,sizeof(short int),1,f) < 1) /* Anzahl Kommandos lesen */
  93.   {
  94.     print_stat(PROMPT_KEYLENGTH);
  95.     wart_ret();
  96.     ende(1, TRUE);
  97.   }
  98.   comm_feld = (comm_typ*)  reserve_mem((mc_index+1) * sizeof(comm_typ));
  99.   index     = (short int*) reserve_mem((mc_index+1) * sizeof(short int));
  100.   for (n_info=i=0;i<=mc_index;i++)  /* Alle Kombinationen einlesen */
  101.     if (fread (&comm_feld[i].blen,sizeof(short int),1,f) < 1)
  102.     { /* Laenge der Kombination einlesen hat nicht geklappt */
  103.       print_stat(PROMPT_KEYCOMM);
  104.       wart_ret();
  105.       ende(1, TRUE);
  106.     }
  107.     else /* Laenge Einlesen hat geklappt, dann eigentliche Kombination lesen */
  108.     {
  109.       if (comm_feld[i].blen > MAX_COMM_LEN)
  110.       { /* Befehl seltsamerweise zu lang */
  111.     print_stat(PROMPT_KEYCOMLEN);
  112.     wart_ret();
  113.     ende(1, TRUE);
  114.       }
  115.       fread (comm_feld[i].befehl,sizeof(short int),comm_feld[i].blen,f);
  116.       fread (&index[i],sizeof(short int),1,f); /* Stringindex lesen */
  117.       comm_feld[i].info_text = NULL;
  118.       if(index[i] > -1)
  119.     for (n_info++,j=0;j<i;j++)  /* Testen, ob Stringindex schon in */
  120.       if (index[j] == index[i]) /* Indextabelle enthalten ist      */
  121.       {
  122.         n_info--;   /* Nur einen weiteren String einlesen,  */
  123.         break;      /* falls neuer Index                    */
  124.       }
  125.     }
  126.  
  127.   /* Jetzt die noetige Anzahl Hilfstrings einlesen */
  128.   for (i=0;i<n_info;i++)
  129.   {
  130.     /* Einen String einlesen und testen, ob er mit '\n' terminiert ist */
  131.     if (!fgets (dummy,255,f) || !(hilf = strchr(dummy,'\n')))
  132.     {
  133.       print_stat(PROMPT_KEYHELP);
  134.       wart_ret();
  135.       ende(1, TRUE);
  136.     }
  137.     *hilf = '\0';  /* '\n' ueberschreiben */
  138.     if (!(hilf = save_text (dummy))) /* Hilfstext im Speicher ablegen */
  139.     {
  140.       print_stat(PROMPT_KEYHELPEM);
  141.       wart_ret();
  142.       ende(1, TRUE);
  143.     }
  144.     for (j=0;j<=mc_index;j++) /* Bei allen Tastenkombinationen, die den */
  145.       if (index[j] == i) /* aktuellen Stringindex aufweisen, Zeiger auf */
  146.     comm_feld[j].info_text = hilf; /* Hilfstext setzen              */
  147.   }
  148.   fclose (f);
  149. }
  150.  
  151. /*****************************************************************************
  152. *
  153. *  Funktion       suche naechsten passenden Befehl (search_next)
  154. *  --------
  155. *
  156. *  Parameter    : eingabe   :
  157. *                   Typ          : short int[]
  158. *                   Wertebereich : Pointer auf integer
  159. *                   Bedeutung    : bisher eingelesene Tastencodes
  160. *
  161. *               : index     :
  162. *                   Typ          : short int
  163. *                   Wertebereich : 0..MAX_COMM_LEN
  164. *                   Bedeutung    : index des zuletzt eingelesenen Zeichens
  165. *
  166. *               : bef_index :
  167. *                   Typ          : short int
  168. *                   Wertebereich : 0..mc_index
  169. *                   Bedeutung    : aktuelle, nicht mehr passende Tasten-
  170. *                                  kombination
  171. *
  172. *  Ergebnis     :
  173. *                   Typ          : short int
  174. *                   Wertebereich : -1,1..mc_index
  175. *                   Bedeutung    : naechste passende Tastenkombination
  176. *
  177. *  Beschreibung : Sucht in comm_feld die naechste auf die bisher eingele-
  178. *                 lesenen Zeichen passende Tastenkombination. Wird keine
  179. *                 entsprechende Kombination gefunden, so wird -1 zurueck-
  180. *                 gegeben.
  181. *
  182. *****************************************************************************/
  183.  
  184. short int search_next(eingabe,index,bef_index)
  185. short int eingabe[];
  186. register short int index,bef_index;
  187. {
  188.   /* *** interne Daten *** */
  189.   register short int *inp, /* Zeiger in alte Eingabe            */
  190.              *bef; /* Zeiger in moeglichen "Kandidaten" */
  191.  
  192.   while(++bef_index <= mc_index) /* Alle weiteren Kombinationen testen */
  193.   {
  194.     for(inp = eingabe,bef = comm_feld[bef_index].befehl;
  195.     (inp <=eingabe+index) && *inp == *bef;inp++,bef++);
  196.     if(inp > eingabe + index) /* passende gefunden */
  197.       return(bef_index);
  198.   }
  199.   return(-1);
  200. }
  201.  
  202. /*****************************************************************************
  203. *
  204. *  Funktion       Tastendruck auswerten (taste)
  205. *  --------
  206. *
  207. *  Parameter    :   w
  208. *                   Typ          : WINDOW *
  209. *                   Wertebereich : Pointer auf curses-Windowstruktur
  210. *                   Bedeutung    : Fenster, in dem Befehl eingelesen werden
  211. *                                  soll
  212. *
  213. *  Ergebnis     :
  214. *                   Typ          : short int
  215. *                   Wertebereich : 0..mc_index+1
  216. *                   Bedeutung    : Interne Nummer der Tastenkombination
  217. *
  218. *  Beschreibung : Es wird eine Taste eingelesen und in der Tabelle nach
  219. *                 einer Kombination beginnend mit dieser Taste gesucht.
  220. *                 Wird keine gefunden, so wird mc_index+1 zurueckgegeben und
  221. *                 die Taste in letter gespeichert.
  222. *                 Wird die Kombination mit dieser Taste abgeschlossen, so
  223. *                 wird die Nummer der gefundenen Kombination zurueckgegeben.
  224. *                 Sonst wird das naechste Zeichen gelesen. Ergibt sich da-
  225. *                 durch keine zulaessige Kombination, so werden alle Zeichen
  226. *                 verworfen. Sonst wird wieder verglichen usw.
  227. *                 Ist das Eingabefenster das Statusfenster, so wird der
  228. *                 Cursor nach Anzeige eines Infotextes nicht positioniert.
  229. *
  230. *****************************************************************************/
  231.  
  232. short int taste(w)
  233. WINDOW *w;
  234. {
  235.   /* *** interne Daten und Initialisierung *** */
  236.   short int hilf;        /* Zwischenspeicher fuer letzte Tastenkombination */
  237.   char      hgz = FALSE  /* Flag, ob ein Hilfstext angezeigt wurde         */
  238. #ifdef MOUSE
  239.         , mouse_akt=FALSE  /* Flag, ob Maus aktiviert ist */
  240.         , macro_active     /* Flag, ob Macro aktiv        */
  241. #endif
  242.                 ;
  243.  
  244.   if (lastcode != -1)
  245.   {
  246.     hilf = lastcode; /* Falls eine Funktion ein "ungetchar" ausgefuehrt hat, */
  247.     lastcode = -1;   /* wird der geungetcharte code zurueckgegeben.          */
  248.     return (hilf);
  249.   }
  250.   index = bef_index = 0; /* Alle Kombinationen kommen in Frage */
  251.   while(1)
  252.   {
  253. #ifdef MOUSE
  254.     if(!mouse_akt && ks_index == -1 && !index) /* Falls kein Macro aktiv ist */
  255.     { /* und noch kein Zeichen eingelesen wurde */
  256. #ifdef OS2
  257.       DosReleaseMutexSem (sem_handle);
  258. #else
  259.       set_mouse_int(MOUSE_MASK);  /* Vor Eingabe Maus aktivieren */
  260. #endif
  261.       mouse_akt = TRUE;
  262.       hide_show (MOUSE_SHOW);
  263.     }
  264. #endif
  265.     letter = eingabe[index] = newwgetch(w); /* Ein Zeichen von Tastatur/Macro */
  266. #ifdef MOUSE
  267.     if(mouse_akt)
  268.     { /* Nach erstem gelesenen Zeichen Maus deaktivieren */
  269.       mouse_akt = FALSE; /* damit Maus nicht zwischen ein Kommando funkt */
  270.       hide_show (MOUSE_HIDE);
  271. #ifdef OS2
  272.       DosRequestMutexSem (sem_handle,-1);
  273. #else
  274.       set_mouse_int(0); 
  275. #endif /* OS2 */
  276.     }
  277. #endif /* MOUSE */
  278.     if(hgz)  /* wurde Hilfstext angezeigt? */
  279.     {
  280.       hgz = FALSE;
  281.       clear_stat();                   /* Hilfstext wieder loeschen              */
  282.       if(w != status)                 /* wenn nicht im Statusfenster eingelesen */
  283.     pos_cursor();                 /* wurde, dann muss Cursor wieder positio-*/
  284.     }                                 /* niert werden */
  285.     if (letter == -1)                 /* War nodelay gesetzt und keine Taste    */
  286.       if(!index)                      /* gedrueckt ? Falls erstes Zeichen */
  287.     return (-1);                  /* eine Kombination, dann -1 zurück */
  288.       else                            /* Sonst -1 ignorieren, da sonst evtl. */
  289.     continue;                     /* Kombination "zerhackt" würde */
  290.     if(comm_feld[bef_index].befehl[index] != eingabe[index])
  291.     {
  292.       /* naechsten passenden Befehl suchen */
  293.       if((bef_index = search_next(eingabe,index,bef_index)) < 0) /* keinen gefunden? */
  294.     if(!index && (letter % 256))    /* normal char and not zero */
  295.     {
  296.       index++;                      /* ein zeichen eingelesen */
  297.       return(bef_index = mc_index+1);
  298.     }
  299.     else                            /* Befehl verwerfen */
  300.     {
  301.       index = bef_index = 0;
  302.       continue;
  303.     }
  304.     }
  305.     if(++index == comm_feld[bef_index].blen) /* passte Zeichen, dann testen, */
  306.       return(bef_index);                /* ob komplette Kombination gelesen. */
  307.     if (helpflag && comm_feld[bef_index].info_text)
  308.     { /* wenn Hilfstexte angezeigt werden sollen und die momentane Kom- */
  309.       hgz = TRUE; /* bination einen hat, dann ausgeben */
  310.       print_hilf (comm_feld[bef_index].info_text);
  311.     }
  312.   }
  313. }
  314.  
  315. /*****************************************************************************
  316. *
  317. *  Funktion       Zeichen aus Puffer oder v. Tastatur lesen (newwgetch)
  318. *  --------
  319. *
  320. *  Parameter    : w         :
  321. *                   Typ          : WINDOW *
  322. *                   Wertebereich : Pointer auf curses-Windowstruktur
  323. *                   Bedeutung    : Fenster, in dem eingegeben werden soll
  324. *
  325. *  Ergebnis     :
  326. *                   Typ          : short int
  327. *                   Wertebereich : curses-Tastenwerte
  328. *                   Bedeutung    : aktuelles Zeichen (s.u.)
  329. *
  330. *  Beschreibung : Diese Funktion liefert das naechste aktuelle Zeichen
  331. *                 zurueck. Dies ist, falls noch Zeichen im Puffer sind, d.h.
  332. *                 ks_index noch nicht -1 ist bzw. in Puffer 0 noch nicht das
  333. *                 letzte Zeichen verarbeitet wurde, das aktuelle Zeichen im
  334. *                 Puffer, andernfalls eine eingelesene Taste.
  335. *                 Zur Erklaerung der Puffer:
  336. *                   ks_index ist der Index des aktuellen Puffers. Ist der
  337. *                   Puffer [ks_index] leer und ks_index>0, so wird in
  338. *                   Puffer [ks_index-1] weitergelesen.
  339. *                   Die Puffer sind in einer Tabelle vom Typ puff_typ[]
  340. *                   gespeichert. Das Strukturelement begin stellt einen
  341. *                   Zeiger auf das aktuelle Element dar, waehrend end auf
  342. *                   das Pufferende zeigt.
  343. *                   keystack ist ein Pointer in den aktuellen Puffer und
  344. *                   zeigt auf das aktuelle Element (falls ks_index>=0);
  345. *                   e_keystack zeigt auf das Ende des aktuellen Puffers.
  346. *
  347. *****************************************************************************/
  348.  
  349. short int newwgetch(w)
  350. WINDOW *w;
  351. {
  352.   short int result;
  353.  
  354.   if(clear_buff) /* Wenn Puffer als zu loeschend markiert sind: */
  355.   {
  356.     while(ks_index > -1)  /* Macro beenden, evtl. freizugebende Strings freigeben */
  357.     {
  358.       if(puff_feld[ks_index].free_flag)
  359.     line_free(puff_feld[ks_index].begin);
  360.       ks_index--;
  361.     }
  362.     clear_buff = FALSE;  /* Flag zuruecksetzen */
  363.   }
  364.   if(ks_index != -1)  /* Wenn ein Puffer aktiv, dann aus Puffer lesen */
  365.   {
  366.     result = *keystack++; /* Dann  aktuelles Pufferzeichen zurueckgeben */
  367.     /* Alle Zeiger auf nächstes Pufferzeichen setzen */
  368.     while (ks_index >= 0 && (!keystack || keystack > e_keystack))
  369.     {
  370.       if(puff_feld[ks_index].anz_rep) /* War es eine Repeat-Funktion ? */
  371.       {
  372.     puff_feld[ks_index].anz_rep--;
  373.     keystack = puff_feld[ks_index].begin; /* Selben Puffer nochmal */
  374.     e_keystack = puff_feld[ks_index].end;
  375.       }
  376.       else /* Puffer war kein Repeat-Puffer, Puffer loeschen */
  377.       {
  378.     if(puff_feld[ks_index].free_flag)   /* falls free_flag gesetzt ist, Puffer freigeben */
  379.       line_free(puff_feld[ks_index].begin);
  380.     /* keine Zeichen mehr im aktuellen Puffer; vielleicht noch im vorigen? */
  381.     if(--ks_index >= 0)     /* noch nicht erster Puffer? */
  382.     {
  383.       keystack = puff_feld[ks_index].current; /* im vorherigen Puffer weiter */
  384.       e_keystack = puff_feld[ks_index].end;
  385.     }
  386.       }
  387.     }
  388.   }
  389.   /* Kein Puffer (mehr) aktiv, von Tastatur lesen */
  390.   else
  391.     result = wgetch(w);
  392.   return result;
  393. }
  394.  
  395.  
  396. /*****************************************************************************
  397. *
  398. *  Funktion       Macro ausfuehren (exec_macro)
  399. *  --------
  400. *
  401. *  Parameter    : mnum      :
  402. *                   Typ          : short int
  403. *                   Wertebereich : 'a' - 'a'+ANZ_MACROS
  404. *                   Bedeutung    : Name des auszufuehrenden Macros
  405. *
  406. *  Beschreibung : Der gewuenschte Macro wird ausgefuehrt, indem auf den
  407. *                 Pufferstapel ein neuer Puffer geschoben wird, in den der
  408. *                 Macrotext kopiert wird. Falls das nicht der erste Puffer
  409. *                 auf dem Stapel ist, wird die Position im alten Puffer
  410. *                 in current abgelegt. Anschliessend wird keystack und
  411. *                 ekeystack korrekt gesetzt.
  412. *
  413. *****************************************************************************/
  414.  
  415. void exec_macro(mnum)
  416. register short int mnum;
  417. {
  418.   /* *** interne Daten *** */
  419.   char dummy[80], /* Zum Zusammenflicken der Fehlermeldung */
  420.        old_delay; /* Zwischenspeicher fuer nodelay-Zustand */
  421.  
  422.   if(mnum>='a' && mnum<='z')  /* exec macro */
  423.     if(macro[mnum-='a'].begin) /* Macro auch nicht leer ? */
  424.       if(ks_index < MACRO_NEST_DEPTH - 1) /* Verschachtelungstiefe OK ? */
  425.       {
  426.     if(ks_index >=0) /* falls schon ein Puffer aktiv, aktuelle Position */
  427.       puff_feld[ks_index].current = keystack;       /* im Puffer merken */
  428.  
  429.     /* Zeiger in neuen Puffer setzen */
  430.     keystack = puff_feld[++ks_index].begin = macro[mnum].begin;
  431.     e_keystack = puff_feld[ks_index].end = macro[mnum].end;
  432.     puff_feld[ks_index].anz_rep = 0; /* Puffer ist nicht zu wiederholen */
  433.     puff_feld[ks_index].free_flag = FALSE;  /* Puffer nach Ausfuehrung  */
  434.       } /* nicht freigeben, da sonst Macrotext freigegeben wuerde */
  435.       else /* zu grosse Verschachtelungstiefe */
  436.       {
  437.     clear_buff = TRUE;  /* beim naechsten Aufruf von newwgetch() Puffer loeschen */
  438. #ifdef OWN_CURSES
  439.     if(old_delay = akt_winp->winp->_dlyflag)
  440.       nodelay(akt_winp->winp,FALSE);  /* falls true eingestellt */
  441. #endif
  442.     print_stat(PROMPT_RECURSION);
  443.     wart_ret();
  444.     clear_stat();
  445. #ifdef OWN_CURSES
  446.     nodelay(akt_winp->winp,old_delay);
  447. #endif
  448.       }
  449.     else /* Macro war leer */
  450.     {
  451.       sprintf(dummy,PROMPT_MACROEMPT,mnum+'a');
  452.       print_err(dummy);
  453.     }
  454. }
  455.  
  456. /*****************************************************************************
  457. *
  458. *  Funktion       String von Tastatur einlesen (newgetstr)
  459. *  --------
  460. *
  461. *  Parameter    : w         :
  462. *                   Typ          : WINDOW *
  463. *                   Wertebereich : Pointer auf curses-Windowstruktur
  464. *                   Bedeutung    : Fenster, in dem Text eingelesen werden soll
  465. *
  466. *                 y         :
  467. *                   Typ          : int
  468. *                   Wertebereich : 0 - Anzahl der Zeilen im Window-1
  469. *                   Bedeutung    : Zeile, in der eingelesen werden soll
  470. *
  471. *                 x         :
  472. *                   Typ          : int
  473. *                   Wertebereich : 0 - Anzahl der Spalten im Window-1
  474. *                   Bedeutung    : Spalte, ab der eingelesen werden soll
  475. *
  476. *                 buff      :
  477. *                   Typ          : char *
  478. *                   Wertebereich : Pointer auf Speicherbereich
  479. *                   Bedeutung    : Speicherbereich, in den Eingabe ge-
  480. *                                  schrieben wird (muss min. max_anz + 1
  481. *                                  Bytes lang sein)
  482. *
  483. *                 max_anz   :
  484. *                   Typ          : int
  485. *                   Wertebereich : 0 - MAX_INT
  486. *                   Bedeutung    : Anzahl maximal einzulesender Zeichen
  487. *                                  = 0 : wartet nur auf RETURN
  488. *                 typ       :
  489. *                   Typ          : int
  490. *                   Wertebereich : GS_NUM, GS_ANY
  491. *                   Bedeutung    : GS_NUM: nur Ziffern einlesen
  492. *                                  GS_ANY: alle Zeichen zulassen
  493. *
  494. *  Beschreibung : Diese Funktion liest mittels newgetch einen String ein.
  495. *                 Hierbei sind die Funktionstasten Backspace (loesche Zeichen
  496. *                 links und bewege Cursor um eine Spalte nach links), Pfeil
  497. *                 links (Cursor um eine Position nach links) und Pfeil rechts
  498. *                 (Cursor um eine Position nach rechts) erlaubt. Maximal
  499. *                 koennen max_anz Zeichen eingegeben werden; versucht man,
  500. *                 mehr Zeichen einzugeben, ertoent ein Piepston und die Ein-
  501. *                 gabe wird ignoriert.
  502. *                 Da bei Backspace die Zeile bis zum Ende geloescht wird,
  503. *                 kann unbeabsichtigt Information geloescht werden (s.u.).
  504. *
  505. *****************************************************************************/
  506.  
  507. void newgetstr(w,y,x,buff,max_anz,typ)
  508. WINDOW *w;
  509. int y,x,max_anz,typ;
  510. char *buff;
  511. {
  512.   /* *** interne Daten und Initialisierung *** */
  513.   short int tmp_inp;        /* Zum einlesen eines Zeichens          */
  514.   int       akt_index = 0,  /* Index in Eingabepuffer               */
  515.         max_index = -1; /* Index fuer letztes Zeichen in Puffer */
  516.  
  517.   if(max_anz < 0)
  518.     return;
  519.  
  520.   buff[akt_index] = '\0';  /* Pufferende markieren */
  521.   do
  522.   {
  523.     wmove(w,y,x + akt_index); /* Cursor an gewuenschte Position */
  524.     wrefresh(w);
  525.     switch(tmp_inp = newwgetch(w))    /* echoing has to be disabled */
  526.     {
  527.       case '\010':          /* Backspace */
  528.     if(akt_index > 0)
  529.     { /* Pufferrest eins nach links kopieren */
  530.       fwdcpy(&buff[akt_index-1],&buff[akt_index]);
  531.       akt_index--;
  532.       max_index--;
  533.       mvwaddstr(w,y,x,buff);
  534.       wclrtoeol(w); /* bis Zeilenende loeschen wg. evtl. ESC-codes */
  535.     }
  536.       break;
  537. #ifndef OS2 /* Bei OS/2 ist alles in einem Zeichen enthalten */
  538.       case '\0':            /* "Escape"-Sequenz */
  539.     switch(newwgetch(w))
  540.     {
  541. #endif
  542.       case KEY_LEFT:        /* Pfeil links */
  543.         if(akt_index > 0)
  544.         akt_index--;
  545.         break;
  546.       case KEY_DC:          /* Delete char */
  547.         if(akt_index <= max_index)
  548.         {
  549.           fwdcpy(&buff[akt_index],&buff[akt_index+1]);
  550.           max_index--;
  551.           mvwaddstr(w,y,x,buff);
  552.           wclrtoeol(w); /* bis Zeilenende loeschen wg. evtl. ESC-codes */
  553.         }
  554.         break;
  555.       case KEY_RIGHT:       /* Pfeil rechts */
  556.         if(akt_index <= max_index)
  557.         akt_index++;
  558.         break;
  559. #ifndef OS2
  560.       default:
  561.         beep();  /* Unbekannte "Escape"-Sequenz */
  562.     }
  563.     break;
  564. #endif
  565.       default:
  566.     /* Bei allen anderen Zeichen ausser dem abschliessenden Zeichen   */
  567.     /* Typ testen und falls korrekt und noch Platz im Puffer, Zeichen */
  568.     /* eintragen */
  569.     if(tmp_inp != END_KEY)
  570.       if(max_index < max_anz-1
  571.       && (typ & GS_NUM && isdigit(tmp_inp) || typ & GS_ANY))
  572.       {
  573.         max_index++;
  574.         revcpy(&buff[akt_index+1],&buff[akt_index]);  /* insert char */
  575.         buff[akt_index++] = tmp_inp;
  576.         mvwaddstr(w,y,x,buff);
  577.       }
  578.       else      /* Typ falsch oder Puffer voll */
  579.         beep();
  580.       break;
  581.     }
  582.   } while(tmp_inp != END_KEY);
  583. }
  584.  
  585. /*****************************************************************************
  586. *
  587. *  Funktion       Kommando-String einlesen (get_comstr)
  588. *  --------
  589. *
  590. *  Parameter    : anf       :
  591. *                   Typ          : short int **
  592. *                   Wertebereich : Pointer auf Pointer auf short int
  593. *                   Bedeutung    : Anfang des Kommandostrings
  594. *
  595. *                 end       :
  596. *                   Typ          : short int **
  597. *                   Wertebereich : Pointer auf Pointer auf short int
  598. *                   Bedeutung    : Ende des Kommandostrings
  599. *
  600. *
  601. *  Beschreibung: Es wird ein Kommandostring eingelesen, der mit RETURN ter-
  602. *                miniert sein muss. Die maximale Laenge ist hierbei durch
  603. *                MAX_MACRO_LEN vorgegeben. Anschliessend wird der eingele-
  604. *                sene String mittels reallocmem und memcpy gesichert und
  605. *                in *anf und *end Anfang bzw. Ende des Strings eingetragen.
  606. *                Moechte man in den Kommandostring ein RETURN einfuegen, so
  607. *                kann man dies mittels der Kombination CTRL-c RETURN, ein
  608. *                CTRL-c laesst sicht durch CTRL-c CTRL-c einfuegen.
  609. *                Hat der Eingabestring (ohne RETURN) die Laenge 0, so wird
  610. *                ein NULL-Pointer zurueckgeliefert.
  611. *
  612. ***************************************************************************/
  613.  
  614. void get_comstr(anf,end)
  615. short int **anf,**end;
  616. {
  617.   /* *** interne Daten und Initialisierung *** */
  618.   register short int bef, /* Zum Einlesen einer Tastenkombination     */
  619.              h;   /* Zum Einlesen des Macrozeichens           */
  620.   short int          mbuff[MAX_MACRO_LEN+1];     /* Eingabepuffer     */
  621.   register int       i=0, /* Index in Eingabepuffer mbuff             */
  622.              i2;  /* Zwischenspeicher fuer Index bzgl. Macros */
  623.  
  624.   print_stat(PROMPT_COMMAND);
  625.   while(funktion[bef = taste(status)] != do_newline) /* code fuer newline ist ende */
  626.   {
  627.     if(i + index > MAX_MACRO_LEN) /* Noch Platz ? */
  628.     {
  629.       clear_stat();
  630.       beep();
  631.       pe_or(PROMPT_KEYLONG);
  632.     }
  633.     else                          /* Es war noch Platz */
  634.       if(funktion[bef] == do_control) /* controlcode einfuegen? */
  635.     mbuff[i++] = newwgetch(status); /* dann ein Zeichen lesen und rein */
  636.       else
  637.     if(funktion[bef] == do_macro && i+index+1 < MAX_MACRO_LEN)  /* Macro-Befehl? */
  638.     { /* zuerst Befehl sichern */
  639.       memcpy(&mbuff[i],eingabe,index * sizeof(short int));
  640.       i += index;
  641.       mbuff[i++] = newwgetch(status); /* Macrozeichen lesen und einfuegen */
  642.     }
  643.     else  /* Kein Macrobefehl */
  644.     {     /* Befehlskombination (eingabe) in Puffer kopieren */
  645.       memcpy(&mbuff[i],eingabe,index * sizeof(short int));
  646.       i += index;
  647.     }
  648.     clear_stat();
  649.     print_stat(PROMPT_COMMAND);
  650.   }
  651.   clear_stat();
  652.   if(!i)  /* Eingabelaenge NULL?*/
  653.     *anf = *end = NULL;
  654.   else
  655.   {
  656.     *anf = (short int *)reserve_mem(i * sizeof(short int));
  657.     *end = &(*anf)[i-1];  /* Zeiger auf Anfang und Ende setzen */
  658.     memcpy(*anf,mbuff,i * sizeof(short int)); /* Kommandostring kopieren */
  659.   }
  660. }
  661.