#include "openaxiom-c-macros.h"
#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"
using namespace OpenAxiom;
#define DELAYED 0
#define IMMEDIATE 1
#define SPECIAL 2
fkey function_key[13];
static const char *defaulteditor = "clefedit";
char editorfilename[100];
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;
}
}
void
define_function_keys(void)
{
char *HOME, path[1024], string[1024];
int key;
int fd;
char type;
for (key = 0; key < 13; key++)
(function_key[key]).str = NULL;
HOME = oa_getenv("HOME");
sprintf(path, "%s/.clef", HOME);
if ((fd = open(path, O_RDONLY)) == -1) {
return;
}
else {
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);
}
}
set_editor_key();
}
#define defof(c) ((c == 'F' || c == 'D' || c == 'E')?(1):(0))
int
get_key(int fd,char * ty)
{
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)
{
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)
{
int count, fd;
int amount = strlen(function_key[key].str);
int id;
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:
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);
fd = open(editorfilename, O_RDWR);
if (fd == -1) {
perror("Opening temp file");
exit(-1);
}
num_proc += 6;
init_flag(buff_flag, buff_pntr);
init_buff(buff, buff_pntr);
buff_pntr = curr_pntr = 0;
current = NULL;
ECHOIT = 0;
while ((num_read = read(fd, in_buff, MAXLINE))) {
do_reading();
}
close(fd);
break;
}
return;
}