/* visual.c no... not C for micro$hit ......dammit */ /* ********************************************************************* * * * Code copyright J. Bradley Christian (phypor), permission for use, * * abuse, whutever, granted as long as full credit given in your * * talkers "help credits", and All help files for this code, and * * the full header kept on all duplications of code... * * * * Disclaimer is that im not liable if this fucks up, for any * * reason at all...no matter whut...in no way is any support * * offered for this... its pretty strightforward, any bugs * * (besides those already noted) send to phypor@benland.muc.edu * * * * "if it breaks, you get to keep both pieces" * * * ********************************************************************* The original src can always be retrieved from : http://benland.muc.edu/phypor/visual.c text http://benland.muc.edu/phypor/visual.c.gz compressed ***************************************************************** Commands for this are: termlines to set terminal lines to number iwinh input window height lines visual [on|off] turn visual on or off divider toggle the window divider ~ to recover the input line (see below) ***************************************************************** Input fixing note: included is a recovery set to allow ppl to get back the input line... talkers are on line-by-line input... so once we write to the upper window, we cant? return the cursor input position to where the person was typing... this leads to a quiet garbled input window at times. the recover simply allows the person to put a ~ at the end of the input and have it stored into p->recovery string, then with the next input it is cat'ed on to the end of it... the mainest way this helps is by echoing whut they typed so far as a prompt... recoving the input... bug to this is once they do so, it may not be backspaced into;)... lifes a bitch aint it?... (suggest useing a ^ command ignore thing to give some leeway) ***************************************************************** Function call note: the ez_tell_player() funct calls will most likely have to be changed as well.....into stack manipulation or your own version of this.... ***************************************************************** bugs n features - as above, input window gets farggled on writes during typing - tiny fugue, xtush, tintin, maybe other nifty telnet clients suppress the scroll reagion stuffs... - scroll back is lost for some ppl with use of scroll reagions ***************************************************************** needed stuff to intergrate into your talker: ==== visual.c ==== just dump this file into your src, and add it into the Makefile... ==== player.h ==== saved p_struct - int termlines saved p_struct - int iwinh nonsaved p_struct - char recovery[IBUFFER_LENGTH] #define DIVIDER (1<<6) #define VISUAL_ON (1<<7) #define SHORT_TIME (1<<8) (as the code is set they are in saved_flags2, this may or may not be needed to be changed for you. the bit offsets most likely will be need to be changed) ==== socket.c ==== extern void scrupr(player *); extern void scrfix(player *); extern void scrdwn(player *); -- tell_player() after PANIC check -- scrupr(p); -- tell_player() at the very bottom -- scrdwn(p); ** the same thing for non_block_tell() ** -- do_prompt() at the topish -- scrdwn(p); -- do_prompt() modification -- tell_player(p, oldstack); <--out write(p->fd, oldstack, strlen(oldstack)); <--in ==== parse.c ==== extern void do_recovery(player *); extern void set_recovery(player *); -- input_for_one() at the topish -- if (p->recovery[0]) do_recovery(p); if (p->ibuffer[strlen(p->ibuffer) - 1] == '~') { set_recovery(p); return; } ==== clist.h ==== this part shouldnt be so hard... just add the commands .... */ #include #include #include #include #include #include #include #include #include #include "ansi.h" #ifdef NON_SENSI /* def NON_SENSI or play with this as needed */ #include "player.h" /* for non-sensisummink and stuffs */ #else #include "proto.h" #endif #include "config.h" #include "fix.h" /* interns in case not extern'd */ void scrupr(player *); void scrdwn(player *); void scrfix(player *); void ddivider(player *); /* functs to move da scroll reagions and sstuffs around */ void scrupr(player * p) { char *scrollroff = "\033[1;%dr\033[%d;1H"; char scrollo[51]; int scri = 0; if (!(p->saved_flags2 & VISUAL_ON)) return; /* this should be cleaned up a bit, but left simple for portablity... (ideally there would be a sys_flag to call for getting this off n on in all the right places) as is, it works, but on shutdowns/wibbles leaves room for improvement */ if (p->flags & (PANIC | CHUCKOUT) || sys_flags & (SHUTDOWN | PANIC)) return; if (p->termlines > 10 && p->iwinh != 0) { if (!(p->saved_flags2 & DIVIDER)) scri = (p->termlines - p->iwinh - 2); else scri = (p->termlines - p->iwinh - 1); sprintf(scrollo, scrollroff, scri, scri); write(p->fd, scrollo, strlen(scrollo)); if (!(p->saved_flags2 & DIVIDER)) ddivider(p); } } void scrdwn(player * p) { char *scrollr = "\033[%d;%dr\033[%d;1H"; char scrollo[51]; int scri = 0; if (!(p->saved_flags2 & VISUAL_ON)) return; if (p->flags & (PANIC | CHUCKOUT) || sys_flags & (SHUTDOWN | PANIC)) return; if (p->termlines > 10 && p->iwinh != 0) { scri = (p->termlines - p->iwinh); sprintf(scrollo, scrollr, scri, p->termlines, p->termlines); write(p->fd, scrollo, strlen(scrollo)); } } void scrfix(player * p) { char *scrollroff = "\033[1;150r\033[150;1H"; write(p->fd, scrollroff, strlen(scrollroff)); } /* this is simply to cat p->ibuffer to the end of p->recover and set the new p->recover to p->ibuffer simply;) */ void do_recovery(player * p) { char toh[IBUFFER_LENGTH * 2]; strncpy(toh, p->recovery, IBUFFER_LENGTH); strcat(toh, p->ibuffer); strncpy(p->ibuffer, toh, IBUFFER_LENGTH - 2); memset(p->recovery, 0, IBUFFER_LENGTH); p->flags |= PROMPT; } /* this next un is to make p->ibuffer prompt, and also put it into p->recover */ void set_recovery(player * p) { int i; memset(p->recovery, 0, IBUFFER_LENGTH); strncpy(p->recovery, p->ibuffer, IBUFFER_LENGTH - 1); for (i = 0; p->recovery[i] != '\0'; i++); p->recovery[i - 1] = '\0'; memset(p->ibuffer, 0, IBUFFER_LENGTH); p->flags &= ~PROMPT; do_prompt(p, p->recovery); } /* divider ffuts */ void ddivider(player * p) { char *dividor; char *spank; char *tformatl = "%a %b %d %I:%M %p"; char *tformats = "%d/%m %H.%M:%S"; char oness[260]; int scri; time_t t; if (!(p->saved_flags2 & VISUAL_ON)) return; dividor = (char *) (malloc(200)); if (!dividor) return; memset(dividor, 0, 200); memset(oness, 0, 260); scri = (p->termlines - p->iwinh - 1); if (1) /* coded always a verbose divider, but this could be changed */ { spank = dividor; sprintf(dividor, "\033[%d;1H\033[K", scri); dividor = strchr(dividor, 0); sprintf(dividor, "=-=-=-=-=-=-=-=-=-=-=-=-"); dividor = strchr(dividor, 0); if (p->mode == NONE) sprintf(dividor, "=-=-=-=- "); else if (p->mode & PASSWORD) sprintf(dividor, "password "); else if (p->mode & ROOMEDIT) sprintf(dividor, "=-room=- "); else if (p->mode & MAILEDIT) sprintf(dividor, "=-mail=- "); else if (p->mode & NEWSEDIT) sprintf(dividor, "=-news=- "); else if (p->mode & CONV) sprintf(dividor, "=cverse- "); else sprintf(dividor, "=-=-=-=- "); dividor = strchr(dividor, 0); if (p->location) sprintf(dividor, "%s.%s ", p->location->owner->lower_name, p->location->id); dividor = strchr(dividor, 0); t = time(0) + 3600 * p->jetlag; strftime(oness, 500, p->saved_flags2 & SHORT_TIME ? tformats : tformatl, localtime(&t)); sprintf(dividor, " %s\n", oness); dividor = end_string(dividor); write(p->fd, spank, strlen(spank)); sprintf(dividor, "\033[%d;1H", (scri - 1)); write(p->fd, dividor, strlen(dividor)); } else { sprintf(dividor, "\033[%d;1H=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=" "-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\033[%d;1H", scri, (scri - 1)); write(p->fd, dividor, strlen(dividor)); } } /* the user interface functions....errr..commands */ void set_termlines(player * p, char * str) { int i = 0; if (!*str) { tell_player(p, " Format : termlines \n"); return; } i = atoi(str); if (i > 150) { tell_player(p, " Gosh! You've'nt got That big a screen.\n"); return; } if (i < 10) { tell_player(p, " Erg, are you Sure your screen is that small?\n"); return; } p->termlines = i; ez_tell_player(p, " Termlines now set to %d\n", p->termlines); } void set_iwinh(player * p, char * str) { int i = 0; if (!*str) { tell_player(p, " Format : iwinh \n"); return; } i = atoi(str); if (i > 15) { tell_player(p, " 15 lines is the biggest you can set.\n"); return; } if (i < 2) { tell_player(p, " 2 is the smallest you can set.\n"); return; } if (i > p->termlines) { tell_player(p, " Your 'termlines' must be greater than iwinh.\n"); return; } p->iwinh = i; ez_tell_player(p, " Input window height now set to %d\n", p->iwinh); } void to_divide(player * p, char * str) { p->saved_flags2 ^= DIVIDER; tell_player(p, " Visual Divider Toggled.\n"); } void visual(player * p, char * str) { if (!strcasecmp("off", str)) { p->saved_flags2 &= ~VISUAL_ON; scrfix(p); } else if (!strcasecmp("on", str)) p->saved_flags2 |= VISUAL_ON; else { tell_player(p, " Format : visual [ off | on ]\n"); return; } if (p->saved_flags2 & VISUAL_ON) { tell_player(p, " Visual Mode ON.\n"); if (p->termlines < 1 || p->iwinh < 1) tell_player(p, " You must have < termlines > and < iwinh > set " "for visual to work.\n"); } else tell_player(p, " Visual Mode OFF.\n"); } void to_short_time(player * p, char * str) { p->saved_flags2 ^= SHORT_TIME; tell_player(p, " Short/long time toggled.\n"); }