/*1* Program source is Copyright 1993 Colten Edwards.2* Central Data Services is granted the right to use this source3* in thier product known as Quote Menu. They are also granted the right4* to modify this source in the advent of problems and or new features5* which they may want to add to the program.6*/789#include <stdlib.h>10#include <ctype.h>11#include <ncurses.h>12#ifdef __EMX__13#include <sys/types.h>14#endif1516#include "ds_cell.h"17#include "ds_keys.h"18#include "func_pr.h"192021/*22* This routine sets the stage for all menu actions except those that are23* specific for a menu.24* Home, PgUp, PgDn, End, Cursor up, Cursor Dn are defined within this source25*/2627/* Get the current menu item.28*29* Save the current position, save the start of the list.30* if key was not a enter key then31* Convert character to uppercase32* While double linked list is not NULL33* if entered key is equal to stored key value34* break loop35* else36* get next double linked list item37* set current item equal38*39* if double linked list item is equal to NULL40* restore current item to entry value.41* return to caller with FALSE { didn't find the a valid key}42* Set redraw = TRUE and43* return TRUE to indicate found valid key44*/4546int get_current(CELL *c) {47dlistptr x = c->start;48dlistptr y = c->current;49if (c->key != ENTER) {50c->key = toupper(c->key);51while (x)52if (c->key == x->datainfo.other) {53break;54} else55x = x->nextlistptr;56c->current = x;57}58if (x == NULL) {59c->current = y;60return FALSE;61}62if(c->ListPaintProc != NULL)63(*c->ListPaintProc)(c);64return TRUE;65}6667/*68* Purpose is set the list start and end values. Main use is for lists that69* stretch longer then the window settings.70*/7172int set_list_end(CELL *c) {73register int x = 0;74if (c->current == NULL)75return x;76c->list_end = c->list_start;77while (x < (c->erow - c->srow)) {78if (c->list_end->nextlistptr)79c->list_end = c->list_end->nextlistptr;80else81break;82x++;83}84return x;85}8687/*88Move the cursor up a line with wrapping89*/9091int wrap_cursor_up (CELL * c)92{93if (!cursor_up (c))94ls_end (c);95return TRUE;96}979899100/*101Move the cursor down a line with wrapping102*/103int wrap_cursor_dn (CELL * c)104{105if (!cursor_dn (c))106ls_home (c);107return TRUE;108}109110/*111Move the cursor up a line.112113Returns: TRUE if successful.114FALSE if it fails. Fails because we are already at the115first item of the list.116*/117118int cursor_up (CELL * c)119{120c->redraw = TRUE;121if (c->current == NULL)122c->redraw = FALSE;123else {124if (c->current == c->list_start) {125if (c->current->prevlistptr) {126c->current = c->list_start = c->current->prevlistptr;127set_list_end(c);128} else129c->redraw = FALSE;130} else {131if (c->current->prevlistptr)132c->current = c->current->prevlistptr;133else134c->redraw = FALSE;135}136}137c->desc_start = 0;138c->cur_pos = CURCOL;139return c->redraw;140}141142/*143Move the cursor down a line.144145Returns: TRUE if successful.146FALSE if it fails. Fails because we are already at the147first item of the list.148*/149150int cursor_dn (CELL * c)151{152c->redraw = TRUE;153if (c->current == NULL)154c->redraw = FALSE;155else {156if (c->current == c->list_end) {157if (c->list_end->nextlistptr) {158c->list_end = c->current = c->list_end->nextlistptr;159if (c->list_start->nextlistptr)160c->list_start = c->list_start->nextlistptr;161} else162c->redraw = FALSE;163} else {164if (c->current->nextlistptr != NULL)165c->current = c->current->nextlistptr;166else167c->redraw = FALSE;168}169}170c->desc_start = 0;171c->cur_pos = CURCOL;172return c->redraw;173}174175/*176* Purpose to pgup through the list values177*/178int ls_pgup (CELL * c)179{180register int pagesize = c->erow - c->srow;181if (c->current == NULL)182return TRUE;183while ((pagesize) && (c->current->prevlistptr != NULL)){184c->current = c->current->prevlistptr;185pagesize--;186}187c->list_start = c->current;188set_list_end(c);189c -> redraw = TRUE;190c->desc_start = 0;191c->cur_pos = CURCOL;192return TRUE;193}194195/*196* Purpose to pgdn through the list values197*/198199int ls_pgdn (CELL * c)200{201register int pagesize = c->erow - c->srow;202if (c->current == NULL)203return TRUE;204while ((pagesize) && (c->current->nextlistptr != NULL)){205c->current = c->current->nextlistptr;206pagesize--;207}208if (pagesize == 0)209c->list_start = c->current;210set_list_end(c);211c->redraw = TRUE;212c->desc_start = 0;213c->cur_pos = CURCOL;214return TRUE;215}216217/*218* purpose to set the home the list.219*/220int ls_home (CELL * c)221{222c->current = c->list_start = c->start;223set_list_end(c);224c->redraw = TRUE;225return TRUE;226}227228/*229* Purpose is to go to end of list.230*/231232int ls_end (CELL * c)233{234int x = 0;235if (c->current == NULL)236return TRUE;237c->current = c->list_end = c->list_start = c->end;238while (x < (c->erow - c->srow)){239if (c->list_start->prevlistptr)240c->list_start = c->list_start->prevlistptr;241else242break;243x++;244}245c -> redraw = TRUE;246return TRUE;247}248249250251/*252* This is the main routine used throughout.253* Purpose is to be a function despatcher.254* On entry255* set termkey = 0256* if we have a list entry procedure then257* exec that procedure. It usely draws the box and creates the list258* Make sure the list start and end are set so we do not overstep boundries259* While terminate key is equal to 0260* set function hit = false261* if list redraw is TRUE and we have a redraw procedure262* exec redraw procedure. Usually draws only items in the list.263* if we have a UpdateStatusProc264* exec Updatestatusproc. Usually displays counts, Menus, etc.265* if termkey is equal to 0266* if othergetkey is TRUE and othergetkeyproc is not equal to NULL267* exec othergetkeyproc. Used to provide edit functions268* else269* call get char function270* Set special to 0. Indicates which function to call, iff found in list.271* Check menu list until end of list (-1) for a matching key value.272* if key and menu item key match and function is not NULL273* set special equal to special number274* exec function and save returned value in hit.275* hit indicates whether or not we have exec'd a function for a key276* break to end of loop277* if hit is FALSE and current_event is not equal to NULL278* exec current event. This allows us to check for both upper and lower279* case keys.280* loop to top and check termkey.281*282* if termkey was set then283* we clear the list and exit function dispatch.284* return terminate key285*/286287int ls_dispatch (CELL * c)288{289long x;290long hit;291292c -> termkey = 0;293if ((*c -> ListEntryProc) != NULL)294x = (*c -> ListEntryProc) (c);295/*296if (c->start == NULL) {297return c->termkey;298}299*/300set_list_end(c);301302while (c -> termkey == 0/* && c->start*/) {303hit = FALSE;304if (c->redraw && ((*c -> ListPaintProc) != NULL))305(*c -> ListPaintProc) (c);306if (*c -> UpdateStatusProc != NULL)307(*c -> UpdateStatusProc) (c);308if (c -> termkey == 0) {309if ((*c -> OtherGetKeyProc) != NULL && c->other_getkey)310c -> key = (*c->OtherGetKeyProc) (c);311else312c->key = getch();313#if 0314c->key = get_char (c, (int)c->menu_bar);315#endif316}317c->special = 0;318for (x = 0; c ->keytable[x].key != -1; x++)319if ((c -> keytable[x].key == c->key) && ((*c->func_table[c->keytable[x].func_num].func) != NULL)) {320c->special = c->keytable[x].func_num;321hit = (*c->func_table[c->keytable[x].func_num].func)(c);322break;323}324if (hit == FALSE && *c->current_event != NULL)325(*c -> current_event) (c);326}327if (*c -> ListExitProc != NULL)328(*c -> ListExitProc) (c);329return c -> termkey;330}331332/*333* Terminate function. Set termkey to the keystroke entered.334*/335336int ls_quit (CELL * c)337{338c->termkey = c->key;339return TRUE;340}341342343344345