static void move_cursor_forward(InputItem *sym) { if (sym->curr_line->buff_pntr == sym->curr_line->len && !sym->curr_line->next) { BeepAtTheUser(); return; } if (sym->curr_line->buff_pntr == sym->curr_line->len || sym->curr_line->buff_pntr == sym->size - 1) { /* I have to move down to a new line */ if (sym->curr_line->next == NULL) { /* now where to move */ BeepAtTheUser(); return; } /* move down line */ clear_cursor(sym); sym->curr_line = sym->curr_line->next; sym->curr_line->buff_pntr = 0; } else { clear_cursor(sym); sym->curr_line->buff_pntr++; } draw_cursor(sym); }
void helpForHyperDoc() { HyperDocPage *page = NULL; /* do not do anything if we are already at the "no more help" page */ if (0 == strcmp(gWindow->page->name, NoMoreHelpPage)) return; /* if no help page recorded, use the standard "no more help" page */ if (!gWindow->page->helppage) gWindow->page->helppage = alloc_string(NoMoreHelpPage); /* if we are on the main help page, use "no more help" page */ if (0 == strcmp(gWindow->page->name, TopLevelHelpPage)) gWindow->page->helppage = alloc_string(NoMoreHelpPage); page = (HyperDocPage *) hash_find(gWindow->fPageHashTable, gWindow->page->helppage); if (page) make_window_link(gWindow->page->helppage); else BeepAtTheUser(); }
static void move_cursor_backward(InputItem *sym) { if (sym->curr_line->buff_pntr == 0) { if (sym->curr_line->prev == NULL) { /* now where to move */ BeepAtTheUser(); return; } else { clear_cursor(sym); /* move up to the previous line */ sym->curr_line = sym->curr_line->prev; if (sym->curr_line->len > sym->size) sym->curr_line->buff_pntr = sym->size - 1; else sym->curr_line->buff_pntr = sym->curr_line->len; } } else { /* just slide back a char. on the current * line */ clear_cursor(sym); sym->curr_line->buff_pntr--; } draw_cursor(sym); }
static void move_cursor_up(InputItem *sym) { int bp = sym->curr_line->buff_pntr; /*int size = sym->size;*/ LineStruct *trace; /* get to the end of the current line */ for (trace = sym->curr_line; trace->prev && trace->prev->len > sym->size; trace = trace->prev) ; if (!trace->prev) BeepAtTheUser(); else { clear_cursor(sym); sym->curr_line = trace->prev; if (bp > sym->curr_line->len) sym->curr_line->buff_pntr = sym->curr_line->len; else sym->curr_line->buff_pntr = bp; draw_cursor(sym); } }
void next_input_focus(void) { InputItem *old_item = gWindow->page->current_item, *new_item, *trace; if (gWindow->page->current_item == NULL || (gWindow->page->current_item->next == NULL && gWindow->page->current_item == gWindow->page->input_list)) { BeepAtTheUser(); return; } /* * Now I should find the new item */ new_item = NULL; trace = old_item->next; if (trace == NULL) new_item = gWindow->page->input_list; else new_item = trace; gWindow->page->current_item = new_item; draw_inputsymbol(old_item); draw_inputsymbol(new_item); }
static int delete_one_char(InputItem *sym) { char c = '\000'; /* This routine moves all the characters back one */ LineStruct *line = sym->curr_line; if (line->len > sym->size) c = move_rest_back(line->next, sym->size); if (c == 0 && line->len == line->buff_pntr) { if (line->next == 0) { BeepAtTheUser(); return 0; } else { delete_eoln(sym); return 1; } } /* * let me just try to do the copy and put the stupid character c if it * exists at the end */ if (line->len <= sym->size) { strncpy(&line->buffer[line->buff_pntr], &(line->buffer[line->buff_pntr + 1]), line->len - line->buff_pntr); if (c == 0) line->buffer[--line->len] = 0; else line->buffer[line->len - 1] = c; } else { strncpy(&(line->buffer[line->buff_pntr]), &(line->buffer[line->buff_pntr + 1]), sym->size - line->buff_pntr); if (c == 0) { line->buffer[sym->size - 1] = 0; line->len = sym->size - 1; } else { if (line->next->len == 0) { line->buffer[sym->size] = 0; line->len = sym->size; } line->buffer[sym->size - 1] = c; } } line->changed = 1; return 1; }
static HyperDocPage * paste_button(PasteNode * paste) { HyperDocPage *page = NULL; auto pastewhere = paste->where; if ( paste->end_node ==NULL || paste->begin_node==NULL || paste->arg_node==NULL ){ BeepAtTheUser(); return NULL; } page=parse_patch(paste); /* paste has changed after this call so use pastewhere*/ if (pastewhere != SourceInputKind{ } && page ) { if (0 == strcmp(page->name, "ErrorPage")) page = NULL; } else BeepAtTheUser(); return page; }
static HyperDocPage * returnlink() { int i; if (gWindow->fMemoStackIndex == 0) { BeepAtTheUser(); return NULL; } else { kill_page(gWindow->page); for (i = gWindow->fDownLinkStackIndex - 1; i >= gWindow->fDownLinkStackTop[gWindow->fMemoStackIndex - 1]; i--) { kill_page(gWindow->fDownLinkStack[i]); } gWindow->fDownLinkStackIndex = gWindow->fDownLinkStackTop[--gWindow->fMemoStackIndex]; return (gWindow->fMemoStack[gWindow->fMemoStackIndex]); } }
void prev_input_focus(void) { InputItem *old_item = gWindow->page->current_item, *new_item, *trace; if (gWindow->page->current_item == NULL) { BeepAtTheUser(); return; } /* * Now I should find the new item */ new_item = NULL; trace = gWindow->page->input_list; if (trace == old_item) { /* * I started at the front of the list, so move forward until I hit * the end */ while (trace->next != NULL) trace = trace->next; new_item = trace; } else { while (trace->next != old_item) trace = trace->next; new_item = trace; } gWindow->page->current_item = new_item; draw_inputsymbol(old_item); draw_inputsymbol(new_item); }
void handle_key(XEvent *event) { char key_buffer[20]; int key_buffer_size = 20; KeySym keysym; XComposeStatus compstatus; int charcount; int display_again = 0; char *name; char *filename; /*char *head = "echo htadd -l ";*/ /*char *blank1 = " ";*/ /*char *blank2 = " \n";*/ char buffer[180]; FILE *filehandle; charcount = XLookupString((XKeyEvent *)event, key_buffer, key_buffer_size, &keysym ,&compstatus); /* 5 args */ key_buffer[charcount] = '\0'; switch (keysym) { case XK_Prior: case XK_F29: scrollUpPage(); break; case XK_Next: case XK_F35: scrollDownPage(); break; case XK_F3: case XK_F12: quitHyperDoc(); break; case XK_F5: if (event->xkey.state & ShiftMask) { name = gWindow->page->name; filename = gWindow->page->filename; sprintf(buffer, "htadd -l %s\n", filename); system(buffer); filehandle = (FILE *) hash_find(&gFileHashTable, filename); fclose(filehandle); hash_delete(&gFileHashTable, filename); gWindow->fMacroHashTable = (HashTable *) halloc(sizeof(HashTable), "macro hash"); hash_init( gWindow->fMacroHashTable, MacroHashSize, (EqualFunction ) string_equal, (HashcodeFunction) string_hash); gWindow->fPatchHashTable = (HashTable *) halloc(sizeof(HashTable), "patch hash"); hash_init( gWindow->fPatchHashTable, PatchHashSize, (EqualFunction ) string_equal, (HashcodeFunction) string_hash); gWindow->fPasteHashTable = (HashTable *) halloc(sizeof(HashTable), "paste hash"); hash_init(gWindow->fPasteHashTable, PasteHashSize, (EqualFunction ) string_equal, (HashcodeFunction) string_hash); gWindow->fCondHashTable = (HashTable *) halloc(sizeof(HashTable), "cond hash"); hash_init( gWindow->fCondHashTable, CondHashSize, (EqualFunction ) string_equal, (HashcodeFunction) string_hash); gWindow->fPageHashTable = (HashTable *) halloc(sizeof(HashTable), "page hash"); hash_init( gWindow->fPageHashTable, PageHashSize, (EqualFunction ) string_equal, (HashcodeFunction) string_hash); make_special_pages(gWindow->fPageHashTable); read_ht_db( gWindow->fPageHashTable, gWindow->fMacroHashTable, gWindow->fPatchHashTable); gWindow->page = (HyperDocPage *) hash_find(gWindow->fPageHashTable, name); if (gWindow->page == NULL) { fprintf(stderr, "lose...gWindow->page for %s is null\n", name); exit(-1); } display_again = 1; } break; case XK_F9: make_window_link(KeyDefsHelpPage); break; case XK_Tab: if (event->xkey.state & ShiftMask) prev_input_focus(); else if (event->xkey.state & ModifiersMask) BeepAtTheUser(); else next_input_focus(); break; case XK_Return: if (!(event->xkey.state & ShiftMask)) { next_input_focus(); break; } /* next ones fall through to input area handling */ case XK_Escape: if (!gWindow->page->current_item) break; case XK_F1: if (!gWindow->page->current_item) { gWindow->page->helppage = alloc_string(NoMoreHelpPage); helpForHyperDoc(); break; } case XK_Home: if (!gWindow->page->current_item) { scrollToFirstPage(); break; } case XK_Up: if (!gWindow->page->current_item) { scrollUp(); break; } case XK_Down: if (!gWindow->page->current_item) { scrollDown(); break; } default: display_again = 0; dialog(event, keysym, key_buffer); XFlush(gXDisplay); break; } if (display_again) { display_page(gWindow->page); gWindow->fWindowHashTable = gWindow->page->fLinkHashTable; } }
static int move_back_one_char(InputItem *sym) { char c = '\000', d = '\000'; int dl = 0; /* This routine moves all the characters back one */ LineStruct *line = sym->curr_line; if (line->len > sym->size) c = move_rest_back(line->next, sym->size); line->changed = 1; if (line->buff_pntr == 0) { /* I am at the front of the line */ if (line->prev == 0) { BeepAtTheUser(); return 0; } else if (line->prev->len <= sym->size) { back_over_eoln(sym); return 1; } else if (line->len > 0) { d = line->buffer[0]; if (line->len <= sym->size) { strncpy(line->buffer, &(line->buffer[1]), line->len - 1); if (c == 0) { line->len--; line->buffer[line->len] = 0; } else line->buffer[line->len - 1] = c; } else { strncpy(line->buffer, &(line->buffer[1]), sym->size - 2); if (c == 0) { line->buffer[sym->size - 1] = 0; line->len--; } else { line->buffer[sym->size - 1] = c; } } } else { /* the line is just going to be thrown away */ if (line->next) line->next->prev = line->prev; line->prev->next = line->next; dec_line_numbers(line->next); sym->num_lines--; free(line->buffer); free(line); dl = 1; } c = d; sym->curr_line = line = line->prev; line->changed = 1; line->buff_pntr = sym->size; } if (line->len <= sym->size) { strncpy(&line->buffer[line->buff_pntr - 1], &(line->buffer[line->buff_pntr]), line->len - line->buff_pntr); if (c == 0) line->buffer[--line->len] = 0; else line->buffer[line->len - 1] = c; } else { strncpy(&(line->buffer[line->buff_pntr - 1]), &(line->buffer[line->buff_pntr]), sym->size - line->buff_pntr); if (c == 0) { line->buffer[sym->size - 1] = 0; line->len = sym->size - 1; } else { if (line->next->len == 0) { line->buffer[sym->size] = 0; line->len = sym->size; } line->buffer[sym->size - 1] = c; } } line->buff_pntr--; if (dl) redraw_win(); else update_inputsymbol(sym); return 1; }
static void delete_rest_of_line(InputItem *sym) { LineStruct *curr_line = sym->curr_line; LineStruct *line=NULL; LineStruct *trash; LineStruct *trace; int num_changed = 0, i; if (curr_line->len > sym->size) { for (line = curr_line->next, num_changed = 0; line != NULL && line->len > 0 && line->len > sym->size; line = line->next, num_changed++) { line->len = 0; line->buffer[0] = 0; line->changed = 1; } num_changed++; } if (num_changed == 0 && curr_line->buff_pntr == curr_line->len) { if (curr_line->len == 0 && curr_line->next) { curr_line->next->prev = curr_line->prev; if (curr_line->prev) curr_line->prev->next = curr_line->next; else sym->lines = curr_line->next; dec_line_numbers(curr_line->next); sym->num_lines--; sym->curr_line = curr_line->next; sym->curr_line->buff_pntr = 0; free(curr_line->buffer); free(curr_line); redraw_win(); } else BeepAtTheUser(); return; } curr_line->len = curr_line->buff_pntr; /* curr_line->buffer[curr_line->len] = NULL; */ for (i = curr_line->len; i <= sym->size + 2; i++) curr_line->buffer[i] = 0; curr_line->changed = 1; if (num_changed) { /* I should get rid of all these lines */ trace = curr_line->next; curr_line->next = line->next; if (line->next) line->next->prev = curr_line; for (; trace && trace != line->next;) { trash = trace; trace = trace->next; free(trash->buffer); free(trash); } decrease_line_numbers(curr_line->next, num_changed); sym->num_lines -= num_changed; redraw_win(); } else update_inputsymbol(sym); }
void dialog(XEvent *event, KeySym keysym, char *buffer) { InputItem *item; item = gWindow->page->current_item; if (item == 0) { if (!((keysym >= XK_Shift_L) && (keysym <= XK_Hyper_R))) /** if something other than a modifier key was hit **/ BeepAtTheUser(); return; } /* * First check if the user had hit an enter key */ if ((keysym == XK_Return) || (keysym == XK_KP_Enter)) enter_new_line(item); /* * Else did the user actual type a character I can understand */ else if (((keysym >= XK_KP_Space) && (keysym <= XK_KP_9)) || ((keysym >= XK_space) && (keysym <= XK_asciitilde))) { /* only handle normal keys */ if (event->xkey.state & UnsupportedModMask) BeepAtTheUser(); else add_buffer_to_sym(buffer, item); } else if ((keysym >= XK_Shift_L) && (keysym <= XK_Hyper_R)) ; /* * do nothing, a modifier was hit */ else if ((keysym >= XK_F2) && (keysym <= XK_F35)) { /* * A function key was hit */ if (strlen(buffer) == 0) BeepAtTheUser(); else /* If I got characters then add it to the buffer */ add_buffer_to_sym(buffer, item); } else switch (keysym) { case XK_Escape: if (event->xkey.state & ModifiersMask) BeepAtTheUser(); else { move_cursor_home(item); delete_rest_of_line(item); } break; case XK_F1: if (event->xkey.state & ModifiersMask) BeepAtTheUser(); else { gWindow->page->helppage = alloc_string(InputAreaHelpPage); helpForHyperDoc(); } break; case XK_Up: if (event->xkey.state & ModifiersMask) BeepAtTheUser(); else move_cursor_up(item); break; case XK_Down: if (event->xkey.state & ModifiersMask) BeepAtTheUser(); else move_cursor_down(item); break; case XK_Delete: if (event->xkey.state & ModifiersMask) BeepAtTheUser(); else delete_char(item); break; case XK_BackSpace: if (event->xkey.state & ModifiersMask) BeepAtTheUser(); else back_over_char(item); break; case XK_Left: if (event->xkey.state & ModifiersMask) BeepAtTheUser(); else move_cursor_backward(item); break; case XK_Right: if (event->xkey.state & ModifiersMask) BeepAtTheUser(); else move_cursor_forward(item); break; case XK_Insert: if (event->xkey.state & ModifiersMask) BeepAtTheUser(); else { gInInsertMode = ((gInInsertMode) ? (0) : (1)); item->curr_line->changed = 1; update_inputsymbol(item); } break; case XK_Home: if (event->xkey.state & ModifiersMask) BeepAtTheUser(); else move_cursor_home(item); break; case XK_End: if (event->xkey.state & ControlMask) /* delete from here to the end of the line */ delete_rest_of_line(item); else if (event->xkey.state & ModifiersMask) BeepAtTheUser(); else move_cursor_end(item); break; default: BeepAtTheUser(); break; } }
HyperDocPage * parse_patch(PasteNode *paste) { TextNode *new_paste; TextNode *end_node; TextNode *begin_node; TextNode *arg_node; TextNode *old; TextNode *next_node; InputItem *paste_item = paste->paste_item; int where = paste->where; GroupItem *g = paste->group; ItemStack *is = paste->item_stack; PatchStore *patch; char *patch_name; int ret_value = 1; /* prepare to throw away the current paste node */ end_node = paste->end_node; next_node = end_node->next; begin_node = paste->begin_node; arg_node = paste->arg_node; old = begin_node->next; /* now read the new stuff and add it in between all this stuff */ switch (where) { case openaxiom_FromFile_input: patch_name = print_to_string(arg_node); patch = (PatchStore *) hash_find(gWindow->fPatchHashTable, patch_name); if (!patch) { fprintf(stderr, "(HyperDoc) Unknown patch name %s\n", patch_name); BeepAtTheUser(); return 0; } if (!patch->loaded) load_patch(patch); input_type = openaxiom_FromString_input; input_string = patch->string; break; case openaxiom_FromSpadSocket_input: input_type = openaxiom_FromSpadSocket_input; ret_value = issue_serverpaste(arg_node); if (ret_value < 0) { paste->where = where; paste->end_node = end_node; paste->arg_node = arg_node; paste->group = g; paste->item_stack = is; paste->haspaste = 1; return 0; } break; case openaxiom_FromUnixFD_input: input_type = openaxiom_FromUnixFD_input; issue_unixpaste(arg_node); break; default: fprintf(stderr, "(HyperDoc) \\parsebutton error: Unknown where\n"); exit(-1); break; } paste->where = 0; paste->end_node = paste->arg_node = paste->begin_node = 0; paste->group = 0; paste->item_stack = 0; paste->haspaste = 0; paste->paste_item = 0; /* set the jump buffer in case it is needed */ if (setjmp(jmpbuf)) { /*** OOOPS, an error occurred ****/ fprintf(stderr, "(HyperDoc) Had an error parsing a patch: Goodbye!\n"); exit(-1); } end_node->next = 0; free_node(old, 1); init_parse_patch(gWindow->page); init_paste_item(paste_item); get_token(); if (token.type != openaxiom_Patch_token) { fprintf(stderr, "(HyperDoc) Pastebutton %s was expecting a patch\n", paste->name); jump(); } if (input_type == openaxiom_FromString_input) { get_token(); if (token.type != openaxiom_Lbrace_token) { token_name(token.type); fprintf(stderr, "(HyperDoc) Unexpected %s \n", ebuffer); print_page_and_filename(); jump(); } get_token(); if (token.type != openaxiom_Word_token) { token_name(token.type); fprintf(stderr, "(HyperDoc) Unexpected %s \n", ebuffer); print_page_and_filename(); jump(); } get_token(); if (token.type != openaxiom_Rbrace_token) { token_name(token.type); fprintf(stderr, "(HyperDoc) Unexpected %s \n", ebuffer); print_page_and_filename(); jump(); } } new_paste = alloc_node(); curr_node = new_paste; parse_HyperDoc(); /* Once I am back, I need only reallign all the text structures */ curr_node->type = openaxiom_Noop_token; curr_node->next = next_node; begin_node->next = new_paste; begin_node->type = openaxiom_Noop_token; free(begin_node->data.text); begin_node->data.text = 0; gWindow->fDisplayedWindow = gWindow->fScrollWindow; repaste_item(); paste_page(begin_node); /* so now I should just be able to disappear */ return gWindow->page; }