diff options
Diffstat (limited to 'src/lib/fnct_key.cc')
-rw-r--r-- | src/lib/fnct_key.cc | 344 |
1 files changed, 344 insertions, 0 deletions
diff --git a/src/lib/fnct_key.cc b/src/lib/fnct_key.cc new file mode 100644 index 00000000..af0d5c28 --- /dev/null +++ b/src/lib/fnct_key.cc @@ -0,0 +1,344 @@ +/* + Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd. + All rights reserved. + Copyright (C) 2007-2013 Gabriel Dos Reis. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + + - Neither the name of The Numerical ALgorithms Group Ltd. nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include <unistd.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <fcntl.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <sys/wait.h> + +#include "cfuns.h" +#include "edible.h" +#include "bsdsignal.h" + + +#include "fnct_key.h" +#include "prt.h" +#include "edin.h" + +/* FIXME: Remove this in complete rewrite */ +using namespace OpenAxiom; + +/** Some constants for functio key defs ****/ +#define DELAYED 0 +#define IMMEDIATE 1 +#define SPECIAL 2 + + +/** Here is the structure for storing bound pf-keys ***/ +fkey function_key[13]; /** Strings which replace function + keys when a key is hit ***/ + +static const char *defaulteditor = "clefedit"; +char editorfilename[100]; + + + +/* + * The following function environment variable clef editor. The command + * should be the one that the user wishes to have execed + */ + +void +set_editor_key(void) +{ + int pid; + + sprintf(editorfilename, "/tmp/clef%d", pid = oa_getpid()); + + if (function_key[12].str == NULL) { + (function_key[12]).type = SPECIAL; + (function_key[12]).str = defaulteditor; + } +} + + + + +/*** This routine id used to find the users function key mappings. It + simply searches the users HOME directory for a file called ".clef". + If found it gets the key bindings from within + *****/ + +void +define_function_keys(void) +{ + char *HOME, path[1024], string[1024]; + int key; + int fd; + char type; + + /** lets initialize the key pointers **/ + for (key = 0; key < 13; key++) + (function_key[key]).str = NULL; + /** see if the user has a .clef file ***/ + HOME = oa_getenv("HOME"); + sprintf(path, "%s/.clef", HOME); + if ((fd = open(path, O_RDONLY)) == -1) { + return; + } + else { + /*** If so, then get the key bindings **/ + while ((key = get_key(fd, &type))) { + get_str(fd, string); + switch (type) { + case 'D': + if (key == 12) { + fprintf(stderr, + "Clef Error: PF12 can only be of type E in .clef\n"); + fprintf(stderr, "Line will be ignored\n"); + type = -1; + } + else { + (function_key[key]).type = DELAYED; + } + break; + case 'F': + if (key == 12) { + fprintf(stderr, + "Clef Error: PF12 can only be of type E in .clef\n"); + fprintf(stderr, "Line will be ignored\n"); + type = -1; + } + else { + (function_key[key]).type = IMMEDIATE; + } + break; + case 'E': + if (key != 12) { + fprintf(stderr, + "Clef Error: PF12 can only be of type E in .clef\n"); + fprintf(stderr, "Line will be ignored\n"); + type = -1; + } + else { + (function_key[key]).type = SPECIAL; + } + break; + } + if (type != -1) + (function_key[key]).str = strdup(string); + } + } + + /* + * Now set the editor function key + */ + set_editor_key(); +} + + +#define defof(c) ((c == 'F' || c == 'D' || c == 'E')?(1):(0)) + +int +get_key(int fd,char * ty) +{ + + /* + * Determines the key number being mapped, and whether it is immediate or + * delay. It reurns the key value, and modifies the parameter type + */ + char keynum[1024]; + int nr; + + nr = read(fd, keynum, 3); + if (nr != -1 && nr != 0) { + if (!defof(keynum[0])) { + return 0; + } + else { + *ty = keynum[0]; + keynum[3] = '\0'; + return (atoi(&keynum[1])); + } + } + else + return 0; +} + +int +get_str(int fd,char * string) +{ + /** Gets the key mapping being bound **/ + char c; + int count = 0; + char *trace = string; + + read(fd, &c, 1); + while (c == ' ') + read(fd, &c, 1); + while (c != '\n') { + count++; + *trace++ = c; + if (read(fd, &c, 1) == 0) + break; + } + *trace = '\0'; + return count; +} + +void +null_fnct(int sig) +{ + return; +} + +void +handle_function_key(int key,int chann) +{ + /** this procedure simply adds the string specified by the function key + to the buffer ****/ + int count, fd; + int amount = strlen(function_key[key].str); + int id; + + /*** This procedure takes the character at in_buff[num_proc] and adds + it to the buffer. It first checks to see if we should be inserting + or overwriting, and then does the appropriate thing *******/ + + switch ((function_key[key]).type) { + case IMMEDIATE: + if (INS_MODE) { + forwardcopy(&buff[curr_pntr + amount], + &buff[curr_pntr], + buff_pntr - curr_pntr); + forwardflag_cpy(&buff_flag[curr_pntr + amount], + &buff_flag[curr_pntr], + buff_pntr - curr_pntr); + for (count = 0; count < amount; count++) { + buff[curr_pntr + count] = (function_key[key].str)[count]; + buff_flag[curr_pntr + count] = '1'; + } + ins_print(curr_pntr, amount + 1); + buff_pntr = buff_pntr + amount; + } + else { + for (count = 0; count < amount; count++) { + buff[curr_pntr + count] = (function_key[key].str)[count]; + buff_flag[curr_pntr + count] = '1'; + myputchar((function_key[key].str)[count]); + } + } + num_proc = num_proc + 6; + curr_pntr = curr_pntr + amount; + buff_pntr = buff_pntr + amount; + send_function_to_child(); + break; + case DELAYED: + if (INS_MODE) { + forwardcopy(&buff[curr_pntr + amount], + &buff[curr_pntr], + buff_pntr - curr_pntr); + forwardflag_cpy(&buff_flag[curr_pntr + amount], + &buff_flag[curr_pntr], + buff_pntr - curr_pntr); + for (count = 0; count < amount; count++) { + buff[curr_pntr + count] = (function_key[key].str)[count]; + buff_flag[curr_pntr + count] = '1'; + } + ins_print(curr_pntr, amount + 1); + buff_pntr = buff_pntr + amount; + } + else { + for (count = 0; count < amount; count++) { + buff[curr_pntr + count] = (function_key[key].str)[count]; + buff_flag[curr_pntr + count] = '1'; + myputchar((function_key[key].str)[count]); + } + } + num_proc = num_proc + 6; + curr_pntr = curr_pntr + amount; + buff_pntr = buff_pntr + amount; + fflush(stdout); + break; + case SPECIAL: + /* fprintf(stderr, "Here I am \n"); */ + if (access(editorfilename, F_OK) < 0) { + fd = open(editorfilename, O_RDWR | O_CREAT, 0666); + write(fd, buff, buff_pntr); + back_up(buff_pntr); + close(fd); + } + else { + if (buff_pntr > 0) { + fd = open(editorfilename, O_RDWR | O_TRUNC); + write(fd, buff, buff_pntr); + back_up(buff_pntr); + close(fd); + } + } + bsdSignal(OPENAXIOM_SIGCHLD, null_fnct,RestartSystemCalls); + switch (id = fork()) { + case -1: + perror("Special key"); + break; + case 0: + execlp((function_key[12]).str, + (function_key[12]).str, + editorfilename, (char*) NULL); + perror("Returned from exec"); + exit(0); + + } + while (wait((int *) 0) < 0); + /** now I should read that file and send all it stuff thru the + reader *****/ + fd = open(editorfilename, O_RDWR); + if (fd == -1) { + perror("Opening temp file"); + exit(-1); + } + num_proc += 6; + + /** reinitialize the buffer ***/ + init_flag(buff_flag, buff_pntr); + init_buff(buff, buff_pntr); + /** reinitialize my buffer pointers **/ + buff_pntr = curr_pntr = 0; + /** reset the ring pointer **/ + current = NULL; + ECHOIT = 0; + while ((num_read = read(fd, in_buff, MAXLINE))) { + do_reading(); + } + close(fd); + break; + } + return; + +} |