]> pd.if.org Git - pd_readline/commitdiff
Very good progress.
authorandy <andy@obsidian.(none)>
Sun, 26 Aug 2012 09:34:33 +0000 (21:34 +1200)
committerandy <andy@obsidian.(none)>
Sun, 26 Aug 2012 09:34:33 +0000 (21:34 +1200)
Notes_and_ideas.txt [new file with mode: 0644]
README
keyhandler.c [new file with mode: 0644]
pd_readline.c [new file with mode: 0644]
pdmenu2.c [new file with mode: 0644]
pdmenu3.c [new file with mode: 0644]
pdmenu4.c [new file with mode: 0644]

diff --git a/Notes_and_ideas.txt b/Notes_and_ideas.txt
new file mode 100644 (file)
index 0000000..1a367a4
--- /dev/null
@@ -0,0 +1,13 @@
+
+ **** A Public Domain readline and command-history utility **** 
+
+ Random thoughts, comments ideas on doing a PD readline and 
+command-history utility.  
+
+Keyboard operation -  Keyboard determines characters sent to 
+computer. Chars are stored in keyboard buffer and then sent. 
+***NOTE*** -  set up editable copy of kbd buffer? 
+
+Keyboard scancodes - make and break codes.  
+  
+
diff --git a/README b/README
index b3a0eca4174a23f22af99ca1d06711d9413a23cb..fa5a32296afd0d509f450c1c78fcde9664a998ac 100644 (file)
--- a/README
+++ b/README
@@ -4,20 +4,20 @@
   This repo is for the (eventual) storage of a public-domain  
 readline-and-command-history implementation. 
 
-Update - 24th Aug 2012 - 
-Added the mg editor files from OpenBSD. 
-I obtained the code from here - 
-ftp://ftp.cc.uoc.gr/mirrors/OpenBSD/src/usr.bin/mg/
+Update - 26th Aug 2012 - 
 
-( It's not so much the editor itself that is the main interest here, 
-but the line-management code. )  
+Very useful progress.  
+Keystroke sequences are now stored in an array of structs. 
+This makes it VERY easy to see the various special flags 
+in a keystroke sequence 
+(e.g. Esc, Ctrl, Alt and so on..... ).  
 
-NOTE - in the mg directory, the file "theo.c" is NOT 
-"public domain" ( but it HAD to be included because of the 
-humour......  ;)    )  
+Still some way to go to get to a REAL readline, but we are 
+"on the way......"
+
+This code is released to the public domain.  
+"Share and enjoy........ ;)  "  
 
-Many thanks to the OpenBSD team and the mg devs 
-(hi Theo - arrrrrrgh, please don't hit me........... ;)     )   
 
  - mooseman 
 
diff --git a/keyhandler.c b/keyhandler.c
new file mode 100644 (file)
index 0000000..af0eb76
--- /dev/null
@@ -0,0 +1,165 @@
+
+
+/*  keyhandler.c  */  
+
+/*                                                     
+  A simple program to handle keys (in particular, function keys, 
+  Ctrl keys, Alt keys and arrow keys). 
+  This code is released to the public domain. 
+  "Share and enjoy...."   ;)  
+*/                    
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <termios.h>
+#include <ctype.h> 
+
+
+void func1(void)
+{  
+   printf("Hey, you entered foo! \n"); 
+} 
+
+void func2(void) 
+{  
+   printf("Hey, you entered bar! \n"); 
+} 
+     
+void alt_a(void)
+{ 
+   printf("Hey, you pressed ALT a! \n"); 
+}   
+
+void alt_b(void)
+{ 
+   printf("Hey, you pressed ALT b! \n"); 
+}   
+
+void ctrl_a(void)
+{ 
+   printf("Hey, you pressed CTRL a! \n"); 
+}   
+
+void ctrl_g(void)
+{ 
+   printf("Hey, you pressed CTRL g! \n"); 
+}   
+
+void up_arrow(void)
+{ 
+   printf("Hey, you pressed the up arrow! \n"); 
+}   
+
+void down_arrow(void)
+{ 
+   printf("Hey, you pressed the down arrow! \n"); 
+}
+
+void left_arrow(void)
+{ 
+   printf("Hey, you pressed the left arrow! \n"); 
+}
+
+void right_arrow(void)
+{ 
+   printf("Hey, you pressed the right arrow! \n"); 
+} 
+
+void f2(void)
+{ 
+   printf("Hey, you pressed F2! \n"); 
+} 
+
+void f3(void)
+{ 
+   printf("Hey, you pressed F3! \n"); 
+} 
+
+void f4(void)
+{ 
+   printf("Hey, you pressed F4! \n"); 
+} 
+
+
+
+    
+int main(void) 
+{ 
+  
+  char word[80]; 
+  char ch; 
+  
+  do { 
+    puts("Enter some text :"); 
+    scanf("%s", word);  
+    
+   if ( !strcmp(word, "foo") ) { 
+      func1(); 
+  } 
+  
+   else if (!strcmp(word, "bar") ) { 
+      func2(); 
+  } 
+  
+   else if (!strcmp(word, "\x1b\x61") ) { 
+      alt_a(); 
+  } 
+  
+   else if (!strcmp(word, "\x1b\x62") ) { 
+      alt_b(); 
+  } 
+    
+   else if (!strcmp(word, "\x07") ) { 
+      ctrl_g(); 
+  } 
+  
+   else if (!strcmp(word, "\x01") ) { 
+      ctrl_a(); 
+  }
+      
+   else if (!strcmp(word, "\x1b\x5b\x41") ) { 
+      up_arrow(); 
+  }   
+      
+   else if (!strcmp(word, "\x1b\x5b\x42") ) { 
+      down_arrow(); 
+  }    
+      
+   else if (!strcmp(word, "\x1b\x5b\x43") ) { 
+      right_arrow(); 
+  }   
+   
+   else if (!strcmp(word, "\x1b\x5b\x44") ) { 
+      left_arrow(); 
+  } 
+         
+   else if (!strcmp(word, "\x1b\x4f\x51") ) { 
+      f2(); 
+  } 
+   
+   else if (!strcmp(word, "\x1b\x4f\x52") ) { 
+      f3(); 
+  }
+  
+   else if (!strcmp(word, "\x1b\x4f\x53") ) { 
+      f4(); 
+  }                    
+                                                                                              
+   else  { 
+   printf("Nope - I do not recognise that phrase.... \n"); 
+  }     
+  
+   printf("Try again? (y/n) : "); 
+   scanf(" %c%*c", &ch);  
+  } 
+  
+    while( toupper(ch) != 'N' );  
+       
+  return 0; 
+
+} 
+
+
+         
diff --git a/pd_readline.c b/pd_readline.c
new file mode 100644 (file)
index 0000000..168a860
--- /dev/null
@@ -0,0 +1,183 @@
+\r
+\r
+/*  pd_readline.c                                           */  \r
+/*  Status (as at 26th Aug 2012) : useful progress.         */ \r
+/*  Keystroke sequences (along with the special flags       */ \r
+/*  like Esc, Ctrl, Alt etc are now stored in a buffer      */ \r
+/*  ( an array of structs ).                                */    \r
+/*  It will still be some time before this is a REAL        */ \r
+/*  readline, but we are "on the way"......                 */     \r
+/*  This code is released to the public domain.             */ \r
+/*  "Share and enjoy...."  ;)                               */  \r
+\r
+\r
+#include <string.h>   \r
+#include <stdio.h> \r
+#include <termios.h>  /* For getch()  */  \r
+\r
+/* This implementation of getch() is from here - */ \r
+/* http://wesley.vidiqatch.org/                  */ \r
+/* Thanks, Wesley!                               */  \r
+static struct termios old, new;\r
+\r
+/* Initialize new terminal i/o settings */\r
+void initTermios(int echo) {\r
+    tcgetattr(0, &old); /* grab old terminal i/o settings */\r
+    new = old; /* make new settings same as old settings */\r
+    new.c_lflag &= ~ICANON; /* disable buffered i/o */\r
+    new.c_lflag &= echo ? ECHO : ~ECHO; /* set echo mode */\r
+    tcsetattr(0, TCSANOW, &new); /* use these new terminal i/o settings now */\r
+}\r
+\r
+\r
+/* Restore old terminal i/o settings */\r
+void resetTermios(void) {\r
+    tcsetattr(0, TCSANOW, &old);\r
+}\r
+\r
+\r
+/* Read 1 character - echo defines echo mode */\r
+char getch_(int echo) {\r
+    char ch;\r
+    initTermios(echo);\r
+    ch = getchar();\r
+    resetTermios();\r
+    return ch;\r
+}\r
+\r
+\r
+/* Read 1 character without echo */\r
+char getch(void) {\r
+    return getch_(0);\r
+}\r
+\r
+\r
+/* Read 1 character with echo */\r
+char getche(void) {\r
+    return getch_(1);\r
+} \r
+\r
+\r
+\r
+/*  Helper function, to let us see if a .history file */ \r
+/*  exists in the current directory.  */ \r
+int fexists(char *fname)\r
+{  \r
+\r
+   FILE *fptr ;        \r
+       \r
+   fptr = fopen(fname, "r") ;  \r
+   \r
+   if ( !fptr )  return -1 ;  /* File does not exist in dir. */        \r
+        \r
+   fclose(fptr);  \r
+   return 0;    /* File DOES exist in dir.  */         \r
+\r
+} \r
+\r
+\r
+ /* Struct to store key sequences */ \r
+typedef struct { \r
+          int fnkey; \r
+          int ctrl; \r
+          int alt ; \r
+       int shf ; \r
+       int esc ; \r
+       int lbr ;  /* For left-bracket ([) of escape sequences */ \r
+       int key; \r
+   } keyseq ;         \r
+\r
+\r
+\r
+\r
+\r
+int main(void)\r
+{\r
+       \r
+  printf("Public Domain Readline \n");              \r
+  printf("NOTE! - at the moment, we are using \n");  \r
+  printf("NON-echoing reads, storing the keystrokes \n");  \r
+  printf("in a buffer \n");   \r
+    \r
+  \r
+  /* Buffer - an array of keyseq structs.                     */  \r
+  /* Note - now that we store the keystrokes in here,         */ \r
+  /* we can look at the various flags and decide whether to   */ \r
+  /* "echo" the key (as normal) or suppress it (as with an    */ \r
+  /* arrow key).                                              */    \r
+  keyseq buffer[80] ;   \r
+  \r
+  /* Buffer "pointer"  */ \r
+  int bufpnt = 0; \r
+  \r
+  \r
+  /* Test for existence of history file. */  \r
+  int exists;  \r
+  exists = fexists(".history"); \r
+  printf("Result: %d \n", exists);  \r
+  \r
+  while(1) \r
+    {  \r
+                   \r
+      int key = getch(); \r
+       \r
+      /* Printable chars. */  \r
+      if ( (key >= 32)  && (key <= 126) ) \r
+      {                \r
+        buffer[bufpnt].key = key;  \r
+        bufpnt += 1; \r
+      }  \r
+                                                                       \r
+      /* Up arrow is 27, 91, 65.    ( ESC [ A )   */   \r
+      /* Down arrow is 27, 91, 66.  ( ESC [ B )   */ \r
+      /* Right arrow is 27, 91, 67. ( ESC [ C )   */ \r
+      /* Left arrow is 27, 91, 68.  ( ESC [ D )   */    \r
+      /* Function keys.     */ \r
+      /* F2 is 27, 79, 81.  */  \r
+      /* F3 is 27, 79, 82.  */  \r
+      /* F4 is 27, 79, 83.  */  \r
+           \r
+                \r
+      else if(key == 27)        \r
+          {  \r
+                         \r
+                         buffer[bufpnt].esc = 1;                        \r
+                         key = getch(); \r
+              if(key == 91)               \r
+              buffer[bufpnt].lbr = 1;                \r
+              key = getch(); \r
+              if( (key >= 65) && (key <= 68) )  \r
+               {                                \r
+                                buffer[bufpnt].key = key;                  \r
+               }                                 \r
+            bufpnt += 1;           \r
+          } \r
+              \r
+                                          \r
+                                                 \r
+    /* The Enter key exits. Enter is 10 decimal */       \r
+        else if(key == 10)  \r
+               { \r
+                        int j ; \r
+                  /* Print the array of structs. */ \r
+                    for (j=0; j<10; j++)       \r
+                    { \r
+                           printf("Fnkey: %d ", buffer[j].fnkey  ) ; \r
+                           printf("Ctrl:  %d ", buffer[j].ctrl   ) ;   \r
+                           printf("Alt:   %d ", buffer[j].alt    ) ; \r
+                           printf("Shf:   %d ", buffer[j].shf    ) ; \r
+                           printf("Esc:   %d ", buffer[j].esc    ) ; \r
+                           printf("Lbr:   %d ", buffer[j].lbr    ) ;  \r
+                   printf("Key:   %d \n", buffer[j].key  ) ; \r
+                }                      \r
+                                         \r
+             break;           \r
+         }  /* Key = Enter */   \r
+    }                \r
+                                      \r
+       return 0;\r
+}  \r
+\r
+\r
+\r
+\r
diff --git a/pdmenu2.c b/pdmenu2.c
new file mode 100644 (file)
index 0000000..746eb31
--- /dev/null
+++ b/pdmenu2.c
@@ -0,0 +1,170 @@
+\r
+\r
+/*  pdmenu.c                                                */  \r
+/*  This code is aimed at helping those who would like to   */ \r
+/*  create menus without using the curses library.          */ \r
+/*  It creates a count variable (which could be used to     */ \r
+/*  keep track of which item is highlighted). Using the     */ \r
+/*  up and down arrow keys increments and decrements the    */ \r
+/*  count variable. Finally, when you press Enter, the      */ \r
+/*  value of the count variable is printed and the program  */ \r
+/*  exits.                                                  */       \r
+/*  This code is released to the public domain.             */ \r
+/*  "Share and enjoy...."  ;)                               */  \r
+\r
+\r
+#include <string.h>   \r
+#include <stdio.h> \r
+#include <termios.h>  /* For getch()  */  \r
+\r
+/* This implementation of getch() is from here - */ \r
+/* http://wesley.vidiqatch.org/                  */ \r
+/* Thanks, Wesley!                               */  \r
+static struct termios old, new;\r
+\r
+/* Initialize new terminal i/o settings */\r
+void initTermios(int echo) {\r
+    tcgetattr(0, &old); /* grab old terminal i/o settings */\r
+    new = old; /* make new settings same as old settings */\r
+    new.c_lflag &= ~ICANON; /* disable buffered i/o */\r
+    new.c_lflag &= echo ? ECHO : ~ECHO; /* set echo mode */\r
+    tcsetattr(0, TCSANOW, &new); /* use these new terminal i/o settings now */\r
+}\r
+\r
+\r
+/* Restore old terminal i/o settings */\r
+void resetTermios(void) {\r
+    tcsetattr(0, TCSANOW, &old);\r
+}\r
+\r
+\r
+/* Read 1 character - echo defines echo mode */\r
+char getch_(int echo) {\r
+    char ch;\r
+    initTermios(echo);\r
+    ch = getchar();\r
+    resetTermios();\r
+    return ch;\r
+}\r
+\r
+\r
+/* Read 1 character without echo */\r
+char getch(void) {\r
+    return getch_(0);\r
+}\r
+\r
+\r
+/* Read 1 character with echo */\r
+char getche(void) {\r
+    return getch_(1);\r
+} \r
+\r
+\r
+\r
+/*  Helper function, to let us see if a .history file */ \r
+/*  exists in the current directory.  */ \r
+int fexists(char *fname)\r
+{  \r
+\r
+   FILE *fptr ;        \r
+       \r
+   fptr = fopen(fname, "r") ;  \r
+   \r
+   if ( !fptr )  return -1 ;  /* File does not exist in dir. */        \r
+        \r
+   fclose(fptr);  \r
+   return 0;    /* File DOES exist in dir.  */         \r
+\r
+} \r
+\r
+\r
+\r
+int main(void)\r
+{\r
+       \r
+  printf("Public Domain Menu Program \n");              \r
+  printf("\nUse the up and down arrow keys then press Enter\n"); \r
+  \r
+  int menunum = 0;            \r
+  \r
+  /* Buffer */  \r
+  char buffer[80] ;   \r
+  \r
+  /* Buffer "pointer"  */ \r
+  int bufpnt = 0; \r
+  \r
+  \r
+  /* Test for existence of history file. */  \r
+  int exists;  \r
+  exists = fexists(".history"); \r
+  printf("Result: %d \n", exists);  \r
+  \r
+  while(1) \r
+    {  \r
+                   \r
+      int key = getch(); \r
+       \r
+      /* Printable chars. */  \r
+      if ( (key >= 32)  && (key <= 126) ) \r
+      { \r
+        buffer[bufpnt] = key; \r
+        bufpnt += 1; \r
+      }  \r
+                                                                       \r
+      /* Up arrow is 27, 91, 65.    ( ESC [ A )   */   \r
+      /* Down arrow is 27, 91, 66.  ( ESC [ B )   */ \r
+      /* Right arrow is 27, 91, 67. ( ESC [ C )   */ \r
+      /* Left arrow is 27, 91, 68.  ( ESC [ D )   */              \r
+      else if(key == 27)  \r
+          {   key = getch(); \r
+              if(key == 91) \r
+              key = getch(); \r
+              if(key == 65)                              \r
+               { puts("You pressed up arrow! \n"); \r
+                        menunum-=1; \r
+                 printf("Menunum is now %d \n", menunum);  \r
+               }  \r
+              else if(key == 66)                              \r
+               { puts("You pressed down arrow! \n"); \r
+                        menunum+=1; \r
+                 printf("Menunum is now %d \n", menunum);  \r
+               }  \r
+              else if(key == 67)                              \r
+               { puts("You pressed right arrow! \n");                   \r
+               }  \r
+              else if(key == 68)                              \r
+               { puts("You pressed left arrow! \n");                    \r
+               }                \r
+          }\r
+              \r
+   /* A few other keys (for testing purposes ) */  \r
+   \r
+   /*    \r
+     else if(key == 97) \r
+            { puts("You pressed the \"a\" key! \n");                    \r
+            }                    \r
+     else if(key == 98) \r
+            { puts("You pressed the \"b\" key! \n");                    \r
+            }   \r
+     else if(key == 99) \r
+            { puts("You pressed the \"c\" key! \n");                    \r
+            }\r
+     else if(key == 100) \r
+            { puts("You pressed the \"d\" key! \n");                    \r
+            }        \r
+     */  \r
+                                          \r
+                                                 \r
+    /* The Enter key exits. Enter is 10 decimal */       \r
+        else if(key == 10)  \r
+               { printf("You pressed ENTER! You chose item %d \n", menunum);   \r
+                 printf("Buffer is %s \n", buffer) ; \r
+          break; }  \r
+    }                \r
+                                      \r
+       return 0;\r
+}  \r
+\r
+\r
+\r
+\r
diff --git a/pdmenu3.c b/pdmenu3.c
new file mode 100644 (file)
index 0000000..6da1936
--- /dev/null
+++ b/pdmenu3.c
@@ -0,0 +1,186 @@
+\r
+\r
+/*  pdmenu.c                                                */  \r
+/*  This code is aimed at helping those who would like to   */ \r
+/*  create menus without using the curses library.          */ \r
+/*  It creates a count variable (which could be used to     */ \r
+/*  keep track of which item is highlighted). Using the     */ \r
+/*  up and down arrow keys increments and decrements the    */ \r
+/*  count variable. Finally, when you press Enter, the      */ \r
+/*  value of the count variable is printed and the program  */ \r
+/*  exits.                                                  */       \r
+/*  This code is released to the public domain.             */ \r
+/*  "Share and enjoy...."  ;)                               */  \r
+\r
+\r
+#include <string.h>   \r
+#include <stdio.h> \r
+#include <termios.h>  /* For getch()  */  \r
+\r
+/* This implementation of getch() is from here - */ \r
+/* http://wesley.vidiqatch.org/                  */ \r
+/* Thanks, Wesley!                               */  \r
+static struct termios old, new;\r
+\r
+/* Initialize new terminal i/o settings */\r
+void initTermios(int echo) {\r
+    tcgetattr(0, &old); /* grab old terminal i/o settings */\r
+    new = old; /* make new settings same as old settings */\r
+    new.c_lflag &= ~ICANON; /* disable buffered i/o */\r
+    new.c_lflag &= echo ? ECHO : ~ECHO; /* set echo mode */\r
+    tcsetattr(0, TCSANOW, &new); /* use these new terminal i/o settings now */\r
+}\r
+\r
+\r
+/* Restore old terminal i/o settings */\r
+void resetTermios(void) {\r
+    tcsetattr(0, TCSANOW, &old);\r
+}\r
+\r
+\r
+/* Read 1 character - echo defines echo mode */\r
+char getch_(int echo) {\r
+    char ch;\r
+    initTermios(echo);\r
+    ch = getchar();\r
+    resetTermios();\r
+    return ch;\r
+}\r
+\r
+\r
+/* Read 1 character without echo */\r
+char getch(void) {\r
+    return getch_(0);\r
+}\r
+\r
+\r
+/* Read 1 character with echo */\r
+char getche(void) {\r
+    return getch_(1);\r
+} \r
+\r
+\r
+\r
+/*  Helper function, to let us see if a .history file */ \r
+/*  exists in the current directory.  */ \r
+int fexists(char *fname)\r
+{  \r
+\r
+   FILE *fptr ;        \r
+       \r
+   fptr = fopen(fname, "r") ;  \r
+   \r
+   if ( !fptr )  return -1 ;  /* File does not exist in dir. */        \r
+        \r
+   fclose(fptr);  \r
+   return 0;    /* File DOES exist in dir.  */         \r
+\r
+} \r
+\r
+\r
+ /* Struct to store key sequences */ \r
+typedef struct { \r
+          int fnkey; \r
+          int ctrl; \r
+          int alt ; \r
+       int shf ; \r
+       int esc ; \r
+       int lbr ;  /* For left-bracket ([) of escape sequences */ \r
+       int key; \r
+   } keyseq ;         \r
+\r
+\r
+\r
+\r
+\r
+int main(void)\r
+{\r
+       \r
+  printf("Public Domain Menu Program \n");              \r
\r
+    \r
+  keyseq myseq;      \r
+       \r
+  \r
+  /* Buffer */  \r
+  keyseq buffer[80] ;   \r
+  \r
+  /* Buffer "pointer"  */ \r
+  int bufpnt = 0; \r
+  \r
+  \r
+  /* Test for existence of history file. */  \r
+  int exists;  \r
+  exists = fexists(".history"); \r
+  printf("Result: %d \n", exists);  \r
+  \r
+  while(1) \r
+    {  \r
+                   \r
+      int key = getch(); \r
+       \r
+      /* Printable chars. */  \r
+      if ( (key >= 32)  && (key <= 126) ) \r
+      { \r
+               myseq.key = key;   \r
+        buffer[bufpnt] = myseq;  \r
+        bufpnt += 1; \r
+      }  \r
+                                                                       \r
+      /* Up arrow is 27, 91, 65.    ( ESC [ A )   */   \r
+      /* Down arrow is 27, 91, 66.  ( ESC [ B )   */ \r
+      /* Right arrow is 27, 91, 67. ( ESC [ C )   */ \r
+      /* Left arrow is 27, 91, 68.  ( ESC [ D )   */    \r
+      /* Function keys.     */ \r
+      /* F2 is 27, 79, 81.  */  \r
+      /* F3 is 27, 79, 82.  */  \r
+      /* F4 is 27, 79, 83.  */  \r
+           \r
+                \r
+      else if(key == 27)        \r
+          {  \r
+                         myseq.key = key; \r
+                         buffer[bufpnt] = myseq; \r
+                         bufpnt += 1; \r
+                         key = getch(); \r
+              if(key == 91) \r
+              myseq.key = key; \r
+              buffer[bufpnt] = myseq;  \r
+              bufpnt += 1;                                     \r
+              key = getch(); \r
+              if( (key >= 65) && (key <= 68) )  \r
+               { \r
+                                myseq.key = key;   \r
+                                buffer[bufpnt] = myseq;  \r
+                 bufpnt += 1;  \r
+               }                                 \r
+          }\r
+              \r
+                                          \r
+                                                 \r
+    /* The Enter key exits. Enter is 10 decimal */       \r
+        else if(key == 10)  \r
+               { \r
+                        int j ; \r
+                  /* Print the array of structs. */ \r
+                    for (j=0; j<10; j++)       \r
+                    { \r
+                           printf("Fnkey: %d ", buffer[j].fnkey  ) ; \r
+                           printf("Ctrl:  %d ", buffer[j].ctrl   ) ;   \r
+                           printf("Alt:   %d ", buffer[j].alt    ) ; \r
+                           printf("Shf:   %d ", buffer[j].shf    ) ; \r
+                           printf("Esc:   %d ", buffer[j].esc    ) ; \r
+                           printf("Lbr:   %d ", buffer[j].lbr    ) ;  \r
+                   printf("Key:   %d \n", buffer[j].key  ) ; \r
+                }                      \r
+                                         \r
+             break;           \r
+         }  /* Key = Enter */   \r
+    }                \r
+                                      \r
+       return 0;\r
+}  \r
+\r
+\r
+\r
+\r
diff --git a/pdmenu4.c b/pdmenu4.c
new file mode 100644 (file)
index 0000000..c8bff2e
--- /dev/null
+++ b/pdmenu4.c
@@ -0,0 +1,185 @@
+\r
+\r
+/*  pd_readline.c                                           */  \r
+/*  Status (as at 26th Aug 2012) : useful progress.         */ \r
+/*  Keystroke sequences (along with the special flags       */ \r
+/*  like Esc, Ctrl, Alt etc are now stored in a buffer      */ \r
+/*  ( an array of structs ).                                */    \r
+/*  It will still be some time before this is a REAL        */ \r
+/*  readline, but we are "on the way"......                 */     \r
+/*  This code is released to the public domain.             */ \r
+/*  "Share and enjoy...."  ;)                               */  \r
+\r
+\r
+#include <string.h>   \r
+#include <stdio.h> \r
+#include <termios.h>  /* For getch()  */  \r
+\r
+/* This implementation of getch() is from here - */ \r
+/* http://wesley.vidiqatch.org/                  */ \r
+/* Thanks, Wesley!                               */  \r
+static struct termios old, new;\r
+\r
+/* Initialize new terminal i/o settings */\r
+void initTermios(int echo) {\r
+    tcgetattr(0, &old); /* grab old terminal i/o settings */\r
+    new = old; /* make new settings same as old settings */\r
+    new.c_lflag &= ~ICANON; /* disable buffered i/o */\r
+    new.c_lflag &= echo ? ECHO : ~ECHO; /* set echo mode */\r
+    tcsetattr(0, TCSANOW, &new); /* use these new terminal i/o settings now */\r
+}\r
+\r
+\r
+/* Restore old terminal i/o settings */\r
+void resetTermios(void) {\r
+    tcsetattr(0, TCSANOW, &old);\r
+}\r
+\r
+\r
+/* Read 1 character - echo defines echo mode */\r
+char getch_(int echo) {\r
+    char ch;\r
+    initTermios(echo);\r
+    ch = getchar();\r
+    resetTermios();\r
+    return ch;\r
+}\r
+\r
+\r
+/* Read 1 character without echo */\r
+char getch(void) {\r
+    return getch_(0);\r
+}\r
+\r
+\r
+/* Read 1 character with echo */\r
+char getche(void) {\r
+    return getch_(1);\r
+} \r
+\r
+\r
+\r
+/*  Helper function, to let us see if a .history file */ \r
+/*  exists in the current directory.  */ \r
+int fexists(char *fname)\r
+{  \r
+\r
+   FILE *fptr ;        \r
+       \r
+   fptr = fopen(fname, "r") ;  \r
+   \r
+   if ( !fptr )  return -1 ;  /* File does not exist in dir. */        \r
+        \r
+   fclose(fptr);  \r
+   return 0;    /* File DOES exist in dir.  */         \r
+\r
+} \r
+\r
+\r
+ /* Struct to store key sequences */ \r
+typedef struct { \r
+          int fnkey; \r
+          int ctrl; \r
+          int alt ; \r
+       int shf ; \r
+       int esc ; \r
+       int lbr ;  /* For left-bracket ([) of escape sequences */ \r
+       int key; \r
+   } keyseq ;         \r
+\r
+\r
+\r
+\r
+\r
+int main(void)\r
+{\r
+       \r
+  printf("Public Domain Readline \n");              \r
+  printf("NOTE! - at the moment, we are using \n");  \r
+  printf("NON-echoing reads, storing the keystrokes \n");  \r
+  printf("in a buffer \n");   \r
+    \r
+  \r
+  /* Buffer - an array of keyseq structs.                     */  \r
+  /* Note - now that we store the keystrokes in here,         */ \r
+  /* we can look at the various flags and decide whether to   */ \r
+  /* "echo" the key (as normal) or suppress it (as with an    */ \r
+  /* arrow key).                                              */    \r
+  keyseq buffer[80] ;   \r
+  \r
+  /* Buffer "pointer"  */ \r
+  int bufpnt = 0; \r
+  \r
+  \r
+  /* Test for existence of history file. */  \r
+  int exists;  \r
+  exists = fexists(".history"); \r
+  printf("Result: %d \n", exists);  \r
+  \r
+  while(1) \r
+    {  \r
+                   \r
+      int key = getch(); \r
+       \r
+      /* Printable chars. */  \r
+      if ( (key >= 32)  && (key <= 126) ) \r
+      {                \r
+        buffer[bufpnt].key = key;  \r
+        bufpnt += 1; \r
+      }  \r
+                                                                       \r
+      /* Up arrow is 27, 91, 65.    ( ESC [ A )   */   \r
+      /* Down arrow is 27, 91, 66.  ( ESC [ B )   */ \r
+      /* Right arrow is 27, 91, 67. ( ESC [ C )   */ \r
+      /* Left arrow is 27, 91, 68.  ( ESC [ D )   */    \r
+      /* Function keys.     */ \r
+      /* F2 is 27, 79, 81.  */  \r
+      /* F3 is 27, 79, 82.  */  \r
+      /* F4 is 27, 79, 83.  */  \r
+           \r
+                \r
+      else if(key == 27)        \r
+          {  \r
+                         \r
+                         buffer[bufpnt].esc = 1; \r
+                         bufpnt += 1; \r
+                         key = getch(); \r
+              if(key == 91)               \r
+              buffer[bufpnt].lbr = 1;  \r
+              bufpnt += 1;                                     \r
+              key = getch(); \r
+              if( (key >= 65) && (key <= 68) )  \r
+               {                                \r
+                                buffer[bufpnt].key = key;  \r
+                 bufpnt += 1;  \r
+               }                                 \r
+          }\r
+              \r
+                                          \r
+                                                 \r
+    /* The Enter key exits. Enter is 10 decimal */       \r
+        else if(key == 10)  \r
+               { \r
+                        int j ; \r
+                  /* Print the array of structs. */ \r
+                    for (j=0; j<20; j++)       \r
+                    { \r
+                           printf("Fnkey: %d ", buffer[j].fnkey  ) ; \r
+                           printf("Ctrl:  %d ", buffer[j].ctrl   ) ;   \r
+                           printf("Alt:   %d ", buffer[j].alt    ) ; \r
+                           printf("Shf:   %d ", buffer[j].shf    ) ; \r
+                           printf("Esc:   %d ", buffer[j].esc    ) ; \r
+                           printf("Lbr:   %d ", buffer[j].lbr    ) ;  \r
+                   printf("Key:   %d \n", buffer[j].key  ) ; \r
+                }                      \r
+                                         \r
+             break;           \r
+         }  /* Key = Enter */   \r
+    }                \r
+                                      \r
+       return 0;\r
+}  \r
+\r
+\r
+\r
+\r