/***************************************************************************** * Duh DRAW * for Linux * (c) Copyleft February 1996 * Ben Fowler * ****************************************************************************/ #include #include #include #include #include #include #include #include #include #include #include #include "ansi-esc.h" #include "ddlogo.h" struct dir_entry { char name[255]; long int size; char sauce[50]; }; #define MAX_DIR_ENTRIES 1024 static struct dir_entry dir_entries[MAX_DIR_ENTRIES]; static int dircount; struct sauce_info { char sig[7]; /* SAUCE00 */ char workname[35]; char author[20]; char group[20]; char date[8]; int unknown; int bla2; int bla3; }; #define CRSUP 14 #define CRSDOWN 15 #define CRSLEFT 16 #define CRSRIGHT 17 #define HOME 18 #define END 19 #define INSERT 20 #define DELETE 21 #define PAGEDOWN 22 #define PAGEUP 23 /* Current x and y of cursor on screen. */ static int x = 0; static int y = 0; /* Current y of cursor in edit buffer. */ static int edit_buffer_y; /* Block start and end positions. */ static int block_upper_left_x; static int block_upper_left_y; static int block_lower_right_x; static int block_lower_right_y; static int insert = 0; /* 0 = overtype , 1 if insert */ static int block = 0; /* 0 if normal , 1 if blockmode */ static int linedraw = 0; /* linedraw = 1, normal = 0 */ static int fore = 7; /* foreground color */ static int back = 0; /* current backround color */ static int text = 0; /* 0 if text , 1 if attrib */ static int blink = 0; /* foreground is blinking? */ static int set = 0; /* current highascii character set */ static int page = 0; /* current page layer */ static int pos = 0; static int par[8]; static int alastline; /* actual lastline of ansi */ static FILE *fileout; static int spacecount; static int charcount; static int olddir; static int newdir; static int savetype; static int changed; static int lastchar; /* * TODO: * * Please replace magic numbers in the code with the constants * below. If there's no existing constant, please invent * one. Hopefully some day we can replace these with variables and * support buffers that are larger than 80x25. -Pekka, 2003-01-10 */ #define EDIT_BUFFER_WIDTH 80 #define EDIT_BUFFER_HEIGHT 1000 #define EDIT_BUFFER_SIZE (EDIT_BUFFER_WIDTH * EDIT_BUFFER_HEIGHT) #define SCREEN_HEIGHT 23 static char filename[81]; /* name of file being edited */ static char statusline[81]; static char input[255]; /* global buffer for user input */ static unsigned int editbuffer[EDIT_BUFFER_SIZE]; static int ques = 0; static int npar = 0; static int attr = 7; static int maxread = 0; static int ishome = 0; static int lattr; static int lastline; static char *colors[] = { "Black", "Red", "Green", "Brown", "Blue", "Purple", "Cyan", "White" }; static int highascii[15][11] = { {218, 191, 192, 217, 196, 179, 195, 180, 193, 194, 197}, /* single */ {201, 187, 200, 188, 205, 186, 204, 185, 202, 203, 206}, /* double horizontal */ {214, 183, 211, 189, 196, 186, 199, 182, 208, 210, 215}, /* double vertical */ {213, 184, 212, 190, 205, 179, 198, 181, 207, 209, 216}, /* double horiz */ {176, 177, 178, 219, 220, 223, 221, 222, 22, 254, 32}, /* solid blocks */ {197, 206, 215, 216, 1, 2, 3, 4, 5, 6, 32}, {16, 17, 18, 19, 21, 23, 25, 29, 30, 31, 32}, {28, 168, 127, 128, 129, 130, 131, 132, 133, 134, 32}, {135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 32}, {145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 32}, {155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 32}, {165, 166, 167, 169, 170, 171, 172, 173, 174, 175, 32}, {224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 32}, {234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 32}, {244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 32} }; static int dir_entry_compare (const void *d1, const void *d2) { struct dir_entry *f1 = ((struct dir_entry *) d1); struct dir_entry *f2 = ((struct dir_entry *) d2); if ((f1->size == -1) && (f2->size == -1)) return (strcmp (f1->name, f2->name)); if (f1->size == -1) return (-1); if (f2->size == -1) return (1); return (strcmp (f1->name, f2->name)); } struct dir_stats { char pathname[255]; unsigned long total; }; static void read_dir_entries (struct dir_stats * stats) { int root; char date[8]; FILE *fp; DIR *dirp; struct dirent *firp; struct stat status; struct sauce_info sauceinfo; dircount = 0; stats->total = 0; root = 0; getcwd (stats->pathname, 255); if (stats->pathname[0] == '/' && stats->pathname[1] == 0) root = 1; dirp = opendir (stats->pathname); if (dirp != NULL) { while ((firp = readdir (dirp)) != NULL) { if (strcmp (firp->d_name, ".") == 0) continue; if (root && (strcmp (firp->d_name, "..") == 0)) continue; stat (firp->d_name, &status); strcpy (dir_entries[dircount].sauce, ""); if (status.st_mode & S_IFDIR) { strcpy (dir_entries[dircount].name, firp->d_name); dir_entries[dircount].size = -1; } else { strcpy (dir_entries[dircount].name, firp->d_name); dir_entries[dircount].size = status.st_size; fp = fopen (firp->d_name, "rb"); if (NULL == fp) { /* Skip this file. */ continue; } fseek (fp, -128, SEEK_END); fread (&sauceinfo, sizeof (struct sauce_info), 1, fp); fclose (fp); if (memcmp (sauceinfo.sig, "SAUCE00", 7) == 0) { date[0] = sauceinfo.date[4]; date[1] = sauceinfo.date[5]; date[2] = '/'; date[3] = sauceinfo.date[6]; date[4] = sauceinfo.date[7]; date[5] = '/'; date[6] = sauceinfo.date[2]; date[7] = sauceinfo.date[3]; sprintf (dir_entries[dircount].sauce, "%-20.20s %-10.10s %-9.9s %-8s", sauceinfo.workname, sauceinfo.author, sauceinfo.group, date); } } stats->total = stats->total + status.st_size; dircount++; /* * Better to kill the program than allow buffer overflow. */ assert(dircount < MAX_DIR_ENTRIES); } closedir (dirp); } qsort (dir_entries, dircount, sizeof (struct dir_entry), dir_entry_compare); dircount--; if (dircount < 0) dircount = 0; } static void print_dir_entry (int h, int entry_y, int curlo) { printf ("\e[%d;1H", entry_y + 1); if (h) printf ("\e[1;37;44m"); else printf ("\e[0;37;40m"); printf ("%-20.20s", dir_entries[curlo].name); if (dir_entries[curlo].size == -1) printf ("\e[1;33m "); else printf ("\e[1;30m %8ld ", dir_entries[curlo].size); printf ("\e[1;36m%-50.50s", dir_entries[curlo].sauce); } static void print_dir_stats (struct dir_stats * stats) { printf ("\e[25;1H\e[0;30;47m"); printf ("%-42.42s %11ld KB total (D)elete (Q)uit ", stats->pathname, stats->total / 1024); } static void refreshdir (struct dir_stats * stats) { int diry; int curlo; printf ("\e[0m\e[2J\e[1;1H"); print_dir_stats (stats); curlo = 0; diry = 0; while ((curlo <= dircount) && (curlo < 24)) { print_dir_entry (0, diry, curlo); diry++; curlo++; } print_dir_entry (1, 0, 0); } static void cgoto () { printf ("\033[%02d;%02dH", y + 1, x + 1); } static void ccolor (void) { printf ("\e[0;%c;%s;%d;%dm", (fore > 7) ? '1' : '0', (blink == 1) ? "5" : "25", (fore & 7) + 30, back + 40); } static int mygetchar (void) { int c; int ex = 0; int scrollstate = ESnormal; fflush (stdout); while (ex != 1) { c = getchar (); if ((c == 27) && (scrollstate == ESesc)) { return (c); } if (c == 27) { scrollstate = ESesc; continue; } switch (scrollstate) { case ESesc: scrollstate = ESnormal; if ((c >= 'a') && (c <= 'z')) { c = c + 256; ex = 1; continue; } switch (c) { case '[': scrollstate = ESsquare; continue; case ']': scrollstate = ESnonstd; continue; case '%': scrollstate = ESpercent; continue; case 'E': continue; case 'M': continue; case 'D': continue; case 'H': continue; case 'Z': continue; case '7': continue; case '8': continue; case '(': scrollstate = ESsetG0; continue; case ')': scrollstate = ESsetG1; continue; case '#': scrollstate = EShash; continue; case '>': /* Numeric keypad */ continue; case '.': c = 256 + '>'; ex = 1; continue; case ',': c = 256 + '<'; ex = 1; continue; case '-': c = 256 + '-'; ex = 1; continue; case '=': c = 256 + '+'; ex = 1; continue; } continue; case ESnonstd: if (c == 'P') { /* palette escape sequence */ for (npar = 0; npar < 7; npar++) par[npar] = 0; npar = 0; scrollstate = ESpalette; continue; } else if (c == 'R') { /* reset palette */ scrollstate = ESnormal; } else scrollstate = ESnormal; continue; case ESpalette: if ((c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f')) { par[npar++] = (c > '9' ? (c & 0xDF) - 'A' + 10 : c - '0'); } else scrollstate = ESnormal; continue; case ESsquare: for (npar = 0; npar < 7; npar++) par[npar] = 0; npar = 0; scrollstate = ESgetpars; if (c == '[') { /* Function key */ scrollstate = ESfunckey; continue; } ques = (c == '?'); if (ques) continue; case ESgetpars: if (c == ';' && npar < 6) { npar++; continue; } else if (c >= '0' && c <= '9') { par[npar] *= 10; par[npar] += c - '0'; continue; } else scrollstate = ESgotpars; case ESgotpars: scrollstate = ESnormal; switch (c) { case 'h': continue; case 'l': continue; case 'n': continue; } if (ques) { ques = 0; continue; } switch (c) { case 'G': case '`': continue; case 'A': c = CRSUP; ex = 1; continue; case 'B': c = CRSDOWN; ex = 1; continue; case 'C': case 'a': c = CRSRIGHT; ex = 1; continue; case 'D': c = CRSLEFT; ex = 1; continue; case 'E': continue; case 'F': continue; case 'd': continue; case 'H': case 'f': continue; case 'J': continue; case 'K': continue; case 'L': continue; case 'M': continue; case 'P': continue; case 'c': continue; case 'g': continue; case 'm': continue; case 'q': /* DECLL - but only 3 leds */ continue; case 'r': continue; case 's': continue; case 'u': continue; case 'X': continue; case '@': continue; case ']': /* setterm functions */ continue; case '~': /* home and function keys */ if (par[0] == 1) { c = HOME; ex = 1; } if (par[0] == 2) { c = INSERT; ex = 1; } if (par[0] == 3) { c = DELETE; ex = 1; } if (par[0] == 4) { c = END; ex = 1; } if (par[0] == 5) { c = PAGEUP; ex = 1; } if (par[0] == 6) { c = PAGEDOWN; ex = 1; } if (par[0] > 6) { c = 256 + par[0]; ex = 1; } continue; } continue; case ESpercent: scrollstate = ESnormal; continue; case ESfunckey: scrollstate = ESnormal; switch (c) { case 'A': c = 256; ex = 1; /* F1 */ continue; case 'B': /* F2 */ c = 257; ex = 1; continue; case 'C': /* F3 */ c = 258; ex = 1; continue; case 'D': /* F4 */ c = 259; ex = 1; continue; case 'E': /* F5 */ c = 260; ex = 1; continue; default: continue; } continue; case EShash: scrollstate = ESnormal; continue; case ESsetG0: scrollstate = ESnormal; continue; case ESsetG1: scrollstate = ESnormal; continue; default: scrollstate = ESnormal; if (c != -1) ex = 1; } /* end switch */ } /* end while */ return (c); } /* end getchar() */ static struct tm * getdatetime () { time_t timer; time (&timer); return localtime (&timer); } /* ask yes or no, v is the default if enter is pressed 1=yes 0=no*/ static int iyesno (int v) /* do yes no quistion */ { int c; while (1) /* Get a character until we have an answer */ { c = mygetchar (); if (c == 13) return (v); /* return? take the default */ if ((c == ' ') && (v == 1)) /* space and default is 1, go cursor right */ { c = CRSRIGHT; } if ((c == ' ') && (v == 0)) /* space and default is 0, go cursor left */ { c = CRSLEFT; } if ((c == 'Y') || (c == 'y')) /* If Y or y, return 1 [yes] */ { printf ("\e[9D"); printf ("\e[1;37;44m Yes \e[0m No "); return (1); } if ((c == 'N') || (c == 'n')) /* If N or n, return 0 [no] */ { printf ("\e[9D"); printf ("\e[0m Yes \e[1;37;44m No "); return (0); } if ((c == CRSRIGHT) && (v == 1)) { printf ("\e[9D"); printf ("\e[0m Yes \e[1;37;44m No "); v = 0; } if ((c == CRSLEFT) && (v == 0)) { printf ("\e[9D"); printf ("\e[1;37;44m Yes \e[0m No "); v = 1; } } } /* highlight yes, unhighlight no */ static int yesno () { printf ("\e[1;37;44m Yes \e[0m No "); return (iyesno (1)); } /* unhighlight yes, highlight no */ static int noyes () { printf ("\e[0m Yes \e[1;37;44m No "); return (iyesno (0)); } int static redrawline (int maxlen) { int i; printf ("\e[u"); /* restore cursor location */ i = 0; while ((input[i] != 0) && (i < maxlen)) { printf ("%c", input[i]); i++; } if (i < maxlen) printf (" \e[D"); /* erase last position ? */ return (i); } static void mygetline (int maxlen) { char redo[255]; int c, i, here, end; if (maxlen > 255) maxlen = 255; strcpy (redo, input); printf ("\e[s"); /* save location */ here = redrawline (maxlen); end = here; while ((c = mygetchar ())) { c = c & 255; switch (c) { case 13: return; case 24: /* ctrl-X */ input[0] = 0; printf ("\e[u"); for (i = 0; i < maxlen; i++) printf (" "); printf ("\e[u"); here = 0; end = 0; break; case 1: /* ctrl-A */ strcpy (input, redo); printf ("\e[u"); for (i = 0; i < maxlen; i++) printf (" "); here = redrawline (maxlen); end = here; break; case 8: case 127: if (here > 0) { here--; i = here; while (i < end) { input[i] = input[i + 1]; i++; } end--; input[end] = 0; printf ("\e[1D \e[1D"); /* cursor left */ if (here < end) { end = redrawline (maxlen); printf ("\e[%dD", end - here); } break; } break; case CRSLEFT: if (here > 0) { here--; printf ("\e[1D"); /* cursor back */ } break; case CRSRIGHT: if (here < end) { here++; printf ("\e[1C"); break; } break; default: if ((here == 0) && (c == ' ')) break; if ((c == ' ') && (input[here - 1] == ' ')) break; if ((end < maxlen) && (c > 31) && (c != 127)) { if (here != end) { i = end; while (i >= here) { input[i + 1] = input[i]; i--; } end++; } input[here] = c; here++; end++; input[end] = 0; if (here < end) { end = redrawline (maxlen); i = end - here; /* */ printf ("\e[%dD", end - here); } else { putc (c, stdout); } } break; } /* end switch */ } /* end while */ } static void ccolorbar (int fg, int bg) { printf ("\e[0;%c;%s;%d;%dm", (fg & 8) ? '1' : '0', (fg & 16) ? "5" : "25", (fg & 7) + 30, bg + 40); } static void drawbar () { printf ("\e[u"); if (back > 0) ccolorbar (back, 0); else ccolorbar (7, 0); printf ("\e[A\e[%dC B ", back + 1); printf ("\e[u"); if ((fore != 0) && (fore != 16)) ccolorbar (fore, 0); else ccolorbar (7, 0); printf ("\e[B\e[%dC F ", fore + 1); printf ("\e[u\e[36C"); ccolorbar (7, 0); printf ("\e[K"); ccolorbar (fore, back); printf ("%s%s on %s", (fore & 8) ? "B." : "", colors[fore & 7], colors[back & 7]); } static void colorbar () { int c, i; if (blink == 1) fore = fore + 16; printf ("\e[s "); /* save current location, bump it two */ c = 219; for (i = 0; i < 32; i++) { ccolorbar (i, 0); putc (c, stdout); } drawbar (); while ((c = mygetchar ()) != 13) switch (c) { case CRSDOWN: if (back > 0) { back--; drawbar (); } break; case CRSUP: if (back < 7) { back++; drawbar (); } break; case CRSLEFT: if (fore > 0) { fore--; drawbar (); } break; case CRSRIGHT: if (fore < 31) { fore++; drawbar (); } break; default: break; } if (fore > 15) { fore = fore - 16; blink = 1; } else blink = 0; } static void clr () { for (pos = 0; pos < EDIT_BUFFER_SIZE; pos++) { editbuffer[pos] = 0x0720; /* defualt color ' ' */ } printf ("\e[0m\e[1;1H\e[2J"); fore = 7; back = 0; changed = 0; pos = 0; } static void readfile () { FILE *fp; x = 0; y = 0; edit_buffer_y = 0; if ((fp = fopen (filename, "rb")) != NULL) { pos = ansi_esc_translate (fp, editbuffer, EDIT_BUFFER_WIDTH, EDIT_BUFFER_HEIGHT); fclose (fp); } } static void printxy () { printf ("\e[25;2H\e[0m\e[0;1;31;40m%2d", x + 1); printf ("\e[25;5H\e[0m\e[0;1;31;40m%4d", edit_buffer_y + 1); ccolor (); cgoto (); } static void status () /* print status line */ { int i; /* print status bar on bottom */ printf ("\e[0m\e[24;1H\e[K%s", statusline); printf ("\e[25;1H"); printf ("\e[0;1;31;40m( , ) \e[1;33;40mPage:1 Set: \e[0;36;44m1= 2= 3= 4= 5= 6= 7= 8= 9= 10= "); printf ("\e[25;10H\e[0m "); printf ("\e[%c;%s;%d;%dm", (fore > 7) ? '1' : '0', (blink == 0) ? "25" : "5", (fore & 7) + 30, back + 40); printf (" Color "); printf ("\e[0m "); if (text == 0) strcpy (input, "\e[1;33;40m Text \e[0m "); else strcpy (input, "\e[1;37;44m Attr \e[0m "); if (linedraw == 1) strcpy (input, "\e[1;34;40m Line \e[0m "); if (block == 1) strcpy (input, "\e[1;32;40m Block\e[0m "); printf ("%s", input); if (insert == 1) printf ("\e[1;37;40mIn\e[0m"); /* fill in the character set */ printf ("\e[25;33H\e[0;1;33;40m%-2d", page + 1); printf ("\e[25;39H\e[0;1;33;40m%-2d", set + 1); printf ("\e[25;43H\e[0;1;33;44m"); for (i = 0; i < 9; i++) printf ("%c\e[C\e[C\e[C", highascii[set][i]); printf ("\e[C%c", highascii[set][9]); printxy (); } static void fprintattr () { int pre; int lbg; int lfg; int lbold; int lflash; int fg; int bg; int abold; int aflash; aflash = 25; if (lattr == attr) /* certain cases :) */ return; if (attr == 7) { fprintf (fileout, "\e[0m"); return; } fg = (attr & 7) + 30; bg = ((attr >> 4) & 7) + 40; lfg = (lattr & 7) + 30; lbg = ((lattr >> 4) & 7) + 40; lflash = 25; lbold = 0; abold = 0; if (attr & 8) abold = 1; if (lattr & 8) lbold = 1; if (attr & 128) aflash = 5; if (lattr & 128) lflash = 5; pre = 0; fprintf (fileout, "\e["); if (lbold != abold) { fprintf (fileout, "%d", abold); if (abold == 0) { if (aflash == 5) fprintf (fileout, ";%d", aflash); if (fg != 7) fprintf (fileout, ";%d", fg); if (bg != 0) fprintf (fileout, ";%d", bg); fputc ('m', fileout); return; } else { if (aflash != lflash) fprintf (fileout, ";%d", aflash); if (lfg != fg) fprintf (fileout, ";%d", fg); if (lbg != bg) fprintf (fileout, ";%d", bg); fputc ('m', fileout); return; } } if (lflash != aflash) { fprintf (fileout, "%d", aflash); pre = 1; } if (lfg != fg) { if (pre == 1) fputc (';', fileout); fprintf (fileout, "%d", fg); pre = 1; } if (lbg != bg) { if (pre == 1) fputc (';', fileout); fprintf (fileout, "%d", bg); } fputc ('m', fileout); } static void fdospace () { char foo[90]; if (spacecount == 0) return; strcpy (foo, " "); if ((((lattr >> 4) & 7) == 0) && (spacecount > 4) && (savetype == 1)) fprintf (fileout, "\e[%dC", spacecount); else { foo[spacecount] = 0; fprintf (fileout, "%s", foo); } charcount = charcount + spacecount; spacecount = 0; } static void fdumpline (int w) /* print one line to file */ { int co; int com; int c; spacecount = 0; charcount = 0; co = 0; com = 79; if (w) { co = block_upper_left_x; com = block_lower_right_x; } for (; co <= com; co++) { attr = (editbuffer[pos + co] >> 8); if ((lattr != attr) || ((pos + co) == 0)) { fdospace (); if (savetype == 1) fprintattr (); lattr = attr; } c = editbuffer[pos + co] & 0xFF; if (c != 32) { fdospace (); fputc (c, fileout); charcount++; } else spacecount++; } if (w) if ((block_lower_right_x - block_upper_left_x) < 79) { fprintf (fileout, "\r\n"); return; } if ((lattr >> 4) & 7) fdospace (); else if (charcount < (com + 1)) fprintf (fileout, "\r\n"); } static void printattr () { int fg; int bg; int abold; int aflash; aflash = 25; fg = (attr & 7); bg = (attr >> 4) & 7; fg = fg + 30; bg = bg + 40; abold = 0; if (attr & 8) abold = 1; if (attr & 128) aflash = 5; printf ("\e[%d;%d;%d;%dm", abold, aflash, fg, bg); } static void dumpline (int start_pos) { int co; for (co = 0; co < EDIT_BUFFER_WIDTH; co++) { attr = (editbuffer[start_pos + co] >> 8); if ((lattr != attr) || (co == 0)) { printattr (); lattr = attr; } putchar (editbuffer[start_pos + co] & 0xFF); } putchar ('\n'); putchar ('\r'); } static void screen_redraw (int redraw_pos) { int i; printf ("\e[2J\e[0;0H"); for (i = 0; i < SCREEN_HEIGHT; i++) { dumpline (redraw_pos + i * EDIT_BUFFER_WIDTH); } } static void ansiscrollup () { if ((pos - (SCREEN_HEIGHT * EDIT_BUFFER_WIDTH)) >= 0) { pos -= 80; screen_redraw (pos - SCREEN_HEIGHT * EDIT_BUFFER_WIDTH); ishome = 0; } else ishome = 1; } static void ansiscrolldown () { if ((pos + EDIT_BUFFER_WIDTH) >= maxread) return; if (lastline < SCREEN_HEIGHT) return; pos += EDIT_BUFFER_WIDTH; screen_redraw (pos - SCREEN_HEIGHT * EDIT_BUFFER_WIDTH); ishome = 0; } static void ansihome () { if (ishome == 1) return; edit_buffer_y = 0; y = 0; ishome = 1; pos = EDIT_BUFFER_WIDTH * (lastline < SCREEN_HEIGHT ? lastline : SCREEN_HEIGHT); screen_redraw (0); } static void ansiend () { int zz; if (lastline < SCREEN_HEIGHT) return; if ((pos + EDIT_BUFFER_WIDTH) >= maxread) return; zz = lastline - SCREEN_HEIGHT; if (zz < 0) zz = 0; zz *= EDIT_BUFFER_WIDTH; pos = zz + (SCREEN_HEIGHT + 1) * EDIT_BUFFER_WIDTH; screen_redraw (pos - SCREEN_HEIGHT * EDIT_BUFFER_WIDTH); ishome = 0; } static void ansipagedown () { if ((lastline - (pos / EDIT_BUFFER_WIDTH)) <= SCREEN_HEIGHT) { ansiend (); } else { screen_redraw (pos); pos += EDIT_BUFFER_WIDTH * SCREEN_HEIGHT; edit_buffer_y = edit_buffer_y + SCREEN_HEIGHT; ishome = 0; } } static void ansipageup () { if ((pos - (EDIT_BUFFER_WIDTH * SCREEN_HEIGHT * 2)) >= 0) { pos -= EDIT_BUFFER_WIDTH * SCREEN_HEIGHT; screen_redraw (pos - EDIT_BUFFER_WIDTH * SCREEN_HEIGHT); edit_buffer_y = edit_buffer_y - SCREEN_HEIGHT; } else ansihome (); } static void docr () { x = 0; if (edit_buffer_y < 999) { edit_buffer_y = edit_buffer_y + 1; if (y < 23) { y = y + 1; printxy (); } else { ansiscrolldown (); status (); } } } static void dochar (int c) { int lx; lx = 78; attr = fore + (back * 16) + (blink * 128); attr = attr << 8; if (insert) while (lx >= x) { editbuffer[(edit_buffer_y * 80) + lx + 1] = editbuffer[(edit_buffer_y * 80) + lx]; lx--; } editbuffer[(edit_buffer_y * 80) + x] = (c & 255) | attr; if (insert) { printf ("\e[%d;1H", y + 1); dumpline ((edit_buffer_y * EDIT_BUFFER_WIDTH) - (SCREEN_HEIGHT * EDIT_BUFFER_WIDTH)); } else putc (c, stdout); if (x < 79) { x = x + 1; printxy (); } else { docr (); } if (edit_buffer_y > alastline) alastline = edit_buffer_y; changed = 1; } static void doattr () { int c; attr = fore + (back * 16) + (blink * 128); attr = attr << 8; c = editbuffer[(edit_buffer_y * 80) + x] & 255; editbuffer[(edit_buffer_y * 80) + x] = c | attr; changed = 1; ccolor (); cgoto (); putc (c, stdout); cgoto (); } void doline (char *ptr) { printf ("\e[0m\e[24;1H\e[K%s", ptr); } static void savefile (int w) /* 0 = whole file,1 = box */ { int i, mi; doline ("Save file ? "); if (yesno () == 0) goto zzyz; savetype = 0; doline ("Save file as ANSI ? "); if (yesno ()) savetype = 1; doline ("Filename to save as : "); if (w) strcpy (input, ""); else strcpy (input, filename); mygetline (60); if (input[0] == 0) goto zzyz; strcpy (filename, input); fileout = fopen (input, "wb"); if (fileout == NULL) goto zzyz; if (savetype == 1) { doline ("Clear screen before ? "); if (yesno ()) fprintf (fileout, "\e[0m\e[2J"); doline ("Home cursor ? "); if (yesno ()) fprintf (fileout, "\e[1;1H"); } i = 0; mi = alastline; if (w) { i = block_upper_left_y; mi = block_lower_right_y; } pos = i * 80; if (w) attr = (editbuffer[pos + block_upper_left_x] >> 8); else attr = (editbuffer[pos] >> 8); if (savetype == 1) { fprintf (fileout, "\e[%s;%s;%d;%dm", (attr & 8) ? "1" : "0", (attr & 128) ? "5" : "25", (attr & 7) + 30, ((attr >> 4) & 7) + 40); lattr = attr; } for (; i <= mi; i++) { pos = i * 80; fdumpline (w); /* 0 = full line,1 = box */ } fclose (fileout); if (w == 0) changed = 0; zzyz: status (); } static void dodelete () { int i; i = x; while (i < 80) { editbuffer[(edit_buffer_y * 80) + i] = editbuffer[(edit_buffer_y * 80) + i + 1]; i++; } editbuffer[(edit_buffer_y * 80) + 79] = 0x0720; printf ("\e[%d;1H", y + 1); pos = edit_buffer_y * 80; dumpline (pos); ccolor (); cgoto (); changed = 1; } static void dorefresh () { screen_redraw ((edit_buffer_y - y) * EDIT_BUFFER_WIDTH); status (); } static void dohelp () { int i; printf ("\e[0m\e[2J\e[1;1H"); printf (" \e[1;37mDuh DRAW Help\r\n\r\n"); printf ("\e[1;37mAlt-A \e[0mToggle Attribute Drawing mode \e[1;37mAlt-N \e[0m\r\n"); printf ("\e[1;37mAlt-B \e[0mBlock Select Mode \e[1;37mAlt-O \e[0m\r\n"); printf ("\e[1;37mAlt-C \e[0mUse Character from Alt-P \e[1;37mAlt-P \e[0m Pickup Character under cursor\r\n"); printf ("\e[1;37mAlt-D \e[0mToggle Line Drawing mode \e[1;37mAlt-Q \e[0m\r\n"); printf ("\e[1;37mAlt-E \e[0mErase current page layer \e[1;37mAlt-R \e[0m\r\n"); printf ("\e[1;37mAlt-F \e[0mSelect fore and back colors \e[1;37mAlt-S \e[0m Save file\r\n"); printf ("\e[1;37mAlt-G \e[0m \e[1;37mAlt-T \e[0m \r\n"); printf ("\e[1;37mAlt-H \e[0mThis help screen \e[1;37mAlt-U \e[0m Pickup Color Under cursor\r\n"); printf ("\e[1;37mAlt-I \e[0mInsert line \e[1;37mAlt-V \e[0m\r\n"); printf ("\e[1;37mAlt-J \e[0mInsert Column \e[1;37mAlt-W \e[0m\r\n"); printf ("\e[1;37mAlt-K \e[0mDelete Column \e[1;37mAlt-X \e[0m Exit DuhDraw\r\n"); printf ("\e[1;37mAlt-L \e[0mLoad file \e[1;37mAlt-Y \e[0m Delete Line\r\n"); printf ("\e[1;37mAlt-M \e[0m \e[1;37mAlt-Z \e[0m\r\n"); printf ("\e[1;37mAlt-[ \e[0mDecrement Page layer \e[1;37mAlt-] \e[0m Increment Page Layer.\r\n"); printf ("\e[1;37mAlt-< \e[0mDecrement HighAscii Set \e[1;37mAlt-> \e[0m Increment HighAscii Set\r\n"); printf ("\e[1;37mShift-F1 \e[0mthru \e[1;37mF10 \e[0mSelect HighAscii Set. \e[1;37mHome \e[0mBeginning of Line/Ansi\r\n"); printf ("\e[1;37mInsert \e[0mToggle Insert mode \e[1;37mEnd \e[0m End of Line/Ansi\r\n"); printf ("\e[1;37mPG UP \e[0mUp one page \e[1;37mPG DN \e[0m Down one page\r\n"); printf ("\e[25;1H\e[1;37;44m%-56.56s", filename); printf ("%24.24s", asctime (getdatetime ())); printf ("\e[22;1H\e[0;1;37m Press a key."); i = mygetchar (); dorefresh (); } static void dolinedraw () { int c = 0; attr = fore + (back * 16) + (blink * 128); attr = attr << 8; switch (newdir) { case 1: /* crs up */ c = highascii[set][5]; if (olddir == 3) c = highascii[set][2]; if (olddir == 4) c = highascii[set][3]; break; case 2: /* crs down */ c = highascii[set][5]; if (olddir == 3) c = highascii[set][0]; if (olddir == 4) c = highascii[set][1]; break; case 3: /* crs left */ c = highascii[set][4]; if (olddir == 1) c = highascii[set][1]; if (olddir == 2) c = highascii[set][3]; break; case 4: /* crs right */ c = highascii[set][4]; if (olddir == 1) c = highascii[set][0]; if (olddir == 2) c = highascii[set][2]; break; default: break; } editbuffer[(edit_buffer_y * 80) + x] = c | attr; ccolor (); cgoto (); putc (c, stdout); cgoto (); olddir = newdir; changed = 1; } static void fixvars () { int c, ok; strcpy (statusline, ""); ishome = 0; lastline = pos / 80; c = lastline * 80; ok = pos - c; if (ok > 0) lastline++; alastline = lastline; maxread = pos; pos = 0; c = 0; ok = 0; lastline = 999; maxread = 79999; linedraw = 0; block = 0; y = 0; x = 0; edit_buffer_y = y; changed = 0; ansihome (); status (); } static void loadfile () { struct dir_stats stats; int curlo; int diry; int ex; int c; curlo = 0; diry = 0; ex = 0; read_dir_entries (&stats); refreshdir (&stats); while (ex != 1) { c = mygetchar (); switch (c) { case 'q': case 'Q': ex = 1; /* escape */ dorefresh (); break; case 'd': case 'D': /* delete file */ if (dir_entries[curlo].size == -1) break; printf ("\e[25;1H\e[0;1;37m\e[KDelete %s ? ", dir_entries[curlo].name); if (yesno ()) { remove (dir_entries[curlo].name); read_dir_entries (&stats); refreshdir (&stats); } else { print_dir_stats (&stats); } break; case 13: /* enter */ if (dir_entries[curlo].size == -1) { chdir (dir_entries[curlo].name); read_dir_entries (&stats); refreshdir (&stats); } else { strcpy (filename, dir_entries[curlo].name); clr (); readfile (); fixvars (); ex = 1; } break; case CRSUP: if (curlo > 0) { print_dir_entry (0, diry, curlo); curlo--; if (diry > 0) { diry--; print_dir_entry (1, diry, curlo); } else { printf ("\e[1;1H\e[L"); /* insert line */ print_dir_stats (&stats); print_dir_entry (1, diry, curlo); } } break; case CRSDOWN: if (curlo < dircount) { print_dir_entry (0, diry, curlo); curlo++; if (diry < 23) /* 0 thru 23 = 1 thru 24 */ { diry++; print_dir_entry (1, diry, curlo); } else { printf ("\e[25;1H\e[0m\e[K"); /* erase stat */ diry++; print_dir_entry (1, diry, curlo); diry--; printf ("\r\n"); print_dir_stats (&stats); } } break; default: break; } } } static void insertline () { int i; if (alastline < 999) { memmove (&(editbuffer[(edit_buffer_y + 1) * 80]), &(editbuffer[edit_buffer_y * 80]), (999 - edit_buffer_y) * 160); for (i = 0; i < 80; i++) editbuffer[(edit_buffer_y * 80) + i] = 0x0720; alastline++; dorefresh (); } changed = 1; } static void deleteline () { if (alastline > 0) { memmove (&(editbuffer[edit_buffer_y * 80]), &(editbuffer[(edit_buffer_y + 1) * 80]), (999 - edit_buffer_y) * 160); alastline--; dorefresh (); } changed = 1; } static void deletecolumn () { int i, j; for (j = x; j < 80; j++) for (i = 0; i < 1000; i++) editbuffer[(i * 80) + j] = editbuffer[(i * 80) + j + 1]; for (i = 0; i < 1000; i++) editbuffer[(i * 80) + 79] = 0x0720; dorefresh (); changed = 1; } static void insertcolumn () { int i, j; if (x == 79) return; for (j = 78; j >= x; j--) for (i = 0; i < 1000; i++) editbuffer[(i * 80) + j + 1] = editbuffer[(i * 80) + j]; for (i = 0; i < 1000; i++) editbuffer[(i * 80) + x] = 0x0720; dorefresh (); changed = 1; } static int flipchar (int cc) { int at; at = cc & 0xFF00; cc = cc & 0xFF; switch (cc) { case 220: cc = 223; break; case 223: cc = 220; break; case 24: cc = 25; break; case 25: cc = 24; break; case 30: cc = 31; break; case 31: cc = 30; break; case 33: cc = 173; break; case 173: cc = 33; break; case 63: cc = 168; break; case 168: cc = 63; break; case 183: cc = 189; break; case 184: cc = 190; break; case 187: cc = 188; break; case 188: cc = 187; break; case 189: cc = 183; break; case 190: cc = 184; break; case 191: cc = 217; break; case 192: cc = 218; break; case 193: cc = 194; break; case 194: cc = 193; break; case 200: cc = 201; break; case 201: cc = 200; break; case 202: cc = 203; break; case 203: cc = 202; break; case 207: cc = 209; break; case 209: cc = 207; break; case 208: cc = 210; break; case 210: cc = 208; break; case 211: cc = 214; break; case 212: cc = 213; break; case 213: cc = 212; break; case 214: cc = 211; break; case 217: cc = 191; break; case 218: cc = 192; break; } return (at | cc); } static void flipblock () { int ty1, ty2, tx; int tempbuf[80]; ty1 = block_upper_left_y; ty2 = block_lower_right_y; while (ty1 <= ty2) { for (tx = block_upper_left_x; tx <= block_lower_right_x; tx++) { tempbuf[tx] = editbuffer[(ty1 * 80) + tx]; /* save line */ editbuffer[(ty1 * 80) + tx] = flipchar (editbuffer[(ty2 * 80) + tx]); /* move bottom to top */ editbuffer[(ty2 * 80) + tx] = flipchar (tempbuf[tx]); } ty1++; ty2--; } } static int mirrorchar (int cc) { int ta; ta = cc & 0xFF00; cc = cc & 0xFF; switch (cc) { case 26: cc = 27; break; case 27: cc = 26; break; case 10: cc = 11; break; case 11: cc = 10; break; case 40: cc = 41; break; case 41: cc = 40; break; case 60: cc = 62; break; case 62: cc = 60; break; case 91: cc = 93; break; case 93: cc = 91; break; case 123: cc = 125; break; case 125: cc = 123; break; case 47: cc = 92; break; case 92: cc = 47; break; case 169: cc = 170; break; case 170: cc = 169; break; case 174: cc = 175; break; case 175: cc = 174; break; case 221: cc = 222; break; case 222: cc = 221; break; case 180: cc = 195; break; case 181: cc = 198; break; case 182: cc = 199; break; case 183: cc = 214; break; case 184: cc = 213; break; case 185: cc = 204; break; case 187: cc = 201; break; case 188: cc = 200; break; case 189: cc = 211; break; case 190: cc = 212; break; case 191: cc = 218; break; case 192: cc = 217; break; case 195: cc = 180; break; case 198: cc = 181; break; case 199: cc = 182; break; case 200: cc = 188; break; case 201: cc = 187; break; case 204: cc = 185; break; case 211: cc = 189; break; case 212: cc = 190; break; case 213: cc = 184; break; case 214: cc = 183; break; case 217: cc = 192; break; case 218: cc = 191; break; case 242: cc = 243; break; case 243: cc = 242; break; } return (ta | cc); } static void mirrorblock () /* left <> right mirror */ { int c1, c2, ty, tx1, tx2; for (ty = block_upper_left_y; ty <= block_lower_right_y; ty++) { tx1 = block_upper_left_x; tx2 = block_lower_right_x; while (tx1 <= tx2) { c1 = editbuffer[(ty * 80) + tx1]; c2 = editbuffer[(ty * 80) + tx2]; editbuffer[(ty * 80) + tx1] = mirrorchar (c2); editbuffer[(ty * 80) + tx2] = mirrorchar (c1); tx1++; tx2--; } } } static void eraseblock () { int i, ty; for (ty = block_upper_left_y; ty <= block_lower_right_y; ty++) for (i = block_upper_left_x; i <= block_lower_right_x; i++) editbuffer[(ty * 80) + i] = 0x0720; } static void transcolor (int tc, int nc) { int ty, i; int ebg, efg; unsigned int c; for (ty = block_upper_left_y; ty <= block_lower_right_y; ty++) for (i = block_upper_left_x; i <= block_lower_right_x; i++) { c = editbuffer[(ty * 80) + i]; ebg = (c & 0x7000) >> 12; efg = (c & 0x0700) >> 8; if (ebg == tc) ebg = nc; if (efg == tc) efg = nc; c = c & 0x88FF; c = c | (efg << 8); c = c | (ebg << 12); editbuffer[(ty * 80) + i] = c; } changed = 1; } static void clear_status_line () { strcpy (statusline, ""); } #define NO_BLOCK 0 #define GET_BLOCK_START_POSITION 1 #define GET_BLOCK_END_POSITION 2 #define GET_BLOCK_COPY_DESTINATION 3 static void doblock () { int c, ex, ty, i; int tc, nc; if (block_upper_left_x > block_lower_right_x) { c = block_lower_right_x; block_lower_right_x = block_upper_left_x; block_upper_left_x = c; } if (block_upper_left_y > block_lower_right_y) { c = block_lower_right_y; block_lower_right_y = block_upper_left_y; block_upper_left_y = c; } ex = 0; block = 0; strcpy (statusline, "(S)ave,(L)oad,(I)nvert,(M)irror,(C)opy,(F)ill,(E)rase,(T)rans," "(ENTER)=Abort : "); status (); while (ex != 1) { c = mygetchar (); switch (c) { case 13: ex = 1; break; case 'S': /* save block */ case 's': savefile (1); ex = 1; break; case 'l': case 'L': /* load block */ ex = 1; break; case 'm': case 'M': /* Mirror block */ mirrorblock (); changed = 1; ex = 1; break; case 'I': case 'i': /* invert - flip block */ flipblock (); changed = 1; ex = 1; break; case 'e': case 'E': /* erase block */ eraseblock (); changed = 1; ex = 1; break; case 'f': case 'F': /* fill block */ doline ("(F)oreground,Bac(K)ground,(B)oth,(C)haracter : "); c = mygetchar (); switch (c) { case 'F': case 'f': for (ty = block_upper_left_y; ty <= block_lower_right_y; ty++) for (i = block_upper_left_x; i <= block_lower_right_x; i++) { c = editbuffer[(ty * 80) + i]; c = c & 0x70FF; c = c | (fore << 8); if (blink) c = c | 0x8000; editbuffer[(ty * 80) + i] = c; } changed = 1; break; case 'K': case 'k': for (ty = block_upper_left_y; ty <= block_lower_right_y; ty++) for (i = block_upper_left_x; i <= block_lower_right_x; i++) { c = editbuffer[(ty * 80) + i]; c = c & 0x8FFF; c = c | (back << 12); editbuffer[(ty * 80) + i] = c; } changed = 1; break; case 'B': case 'b': attr = fore | (back << 4); if (blink) attr = attr | 128; attr = attr << 8; for (ty = block_upper_left_y; ty <= block_lower_right_y; ty++) for (i = block_upper_left_x; i <= block_lower_right_x; i++) { c = editbuffer[(ty * 80) + i] & 0xFF; c = c | attr; editbuffer[(ty * 80) + i] = c; } changed = 1; break; case 'C': case 'c': doline ("Press character to fill block with : "); c = mygetchar (); switch (c) { case 256: /* F1 */ c = highascii[set][0]; break; case 257: /* F2 */ c = highascii[set][1]; break; case 258: /* F3 */ c = highascii[set][2]; break; case 259: /* F4 */ c = highascii[set][3]; break; case 260: /* F5 */ c = highascii[set][4]; break; case 256 + 17: /* F6 */ c = highascii[set][5]; break; case 256 + 18: /* F7 */ c = highascii[set][6]; break; case 256 + 19: /* F8 */ c = highascii[set][7]; break; case 256 + 20: /* F9 */ c = highascii[set][8]; break; case 256 + 21: /* F10 */ c = highascii[set][9]; break; case 256 + 'c': /* alt-C */ c = lastchar; default: break; } if (c > 255) break; attr = fore | (back << 4); if (blink) attr = attr | 128; attr = attr << 8; c = c | attr; for (ty = block_upper_left_y; ty <= block_lower_right_y; ty++) for (i = block_upper_left_x; i <= block_lower_right_x; i++) editbuffer[(ty * 80) + i] = c; changed = 1; break; default: break; } ex = 1; break; case 'C': case 'c': /* copy block */ doline ("Goto x and y position for upper left corner of block " "and press enter."); block = GET_BLOCK_COPY_DESTINATION; return; case 't': case 'T': /* translate color scheme to color scheme */ ex = 1; doline ("Select color to operate on \e[31m1 \e[32m2 \e[33m3 \e[34m4 \e[35m5 \e[36m6 \e[37m7 \e[0m: "); c = mygetchar (); if ((c < '0') || (c > '7')) break; tc = c - '0'; doline ("Select color to convert to \e[31m1 \e[32m2 \e[33m3 \e[34m4 \e[35m5 \e[36m6 \e[37m7 \e[0m: "); c = mygetchar (); if ((c < '0') || (c > '7')) break; nc = c - '0'; transcolor (tc, nc); changed = 1; break; default: break; } } clear_status_line(); dorefresh(); } static int get_block_height () { /* If start and end positions are the same, we have a block of size one. */ return (block_lower_right_y - block_upper_left_y + 1); } static int get_block_width () { /* If start and end positions are the same, we have a block of size one. */ return (block_lower_right_x - block_upper_left_x + 1); } static int get_block_size () { return (get_block_height() * get_block_width()); } #define EDIT_BUFFER_OFFSET(_x, _y) ((_y * EDIT_BUFFER_WIDTH) + _x) static unsigned int get_edit_buffer (int buffer_x, int buffer_y) { return editbuffer[EDIT_BUFFER_OFFSET(buffer_x, buffer_y)]; } static void put_edit_buffer (int buffer_x, int buffer_y, unsigned int value) { editbuffer[EDIT_BUFFER_OFFSET(buffer_x, buffer_y)] = value; } #define BLOCK_BUFFER_OFFSET(_x, _y) ((_y * get_block_width()) + _x) static unsigned int get_block_buffer (unsigned int * buffer, int buffer_x, int buffer_y) { return buffer[BLOCK_BUFFER_OFFSET(buffer_x, buffer_y)]; } static void put_block_buffer (unsigned int * buffer, int buffer_x, int buffer_y, unsigned int value) { buffer[BLOCK_BUFFER_OFFSET(buffer_x, buffer_y)] = value; } static void copy_block_from_edit_buffer (unsigned int * block_buffer) { int buffer_x, buffer_y; for (buffer_y = 0; buffer_y < get_block_height(); buffer_y++) { if ((buffer_y + block_upper_left_y) >= EDIT_BUFFER_HEIGHT) break; for (buffer_x = 0; buffer_x < get_block_width(); buffer_x++) { if ((buffer_x + block_upper_left_x) >= EDIT_BUFFER_WIDTH) break; put_block_buffer(block_buffer, buffer_x, buffer_y, get_edit_buffer(buffer_x + block_upper_left_x, buffer_y + block_upper_left_y)); } } } static void copy_block_to_edit_buffer(unsigned int * block_buffer, int destination_x, int destination_y) { int block_x, block_y; for (block_y = 0; block_y < get_block_height(); block_y++) { if ((block_y + destination_y) >= EDIT_BUFFER_HEIGHT) break; for (block_x = 0; block_x < get_block_width(); block_x++) { if ((block_x + destination_x) >= EDIT_BUFFER_WIDTH) break; put_edit_buffer(block_x + destination_x, block_y + destination_y, get_block_buffer(block_buffer, block_x, block_y)); } } } static void copyblock () { unsigned int * block_buffer; assert(block_upper_left_x <= block_lower_right_x); assert(block_upper_left_y <= block_lower_right_y); block_buffer = (unsigned int *) malloc(get_block_size() * sizeof(unsigned int)); if (block_buffer == NULL) { doline ("Block copy operation aborted: Malloc failed."); mygetchar(); return; } copy_block_from_edit_buffer(block_buffer); copy_block_to_edit_buffer(block_buffer, x, edit_buffer_y); free(block_buffer); } static void editloop () { lastchar = 32; for (;;) { int c; c = mygetchar (); switch (c) { case 'l': case 'L': if ((block != NO_BLOCK) && (block != GET_BLOCK_COPY_DESTINATION)) { /* * Block start and end position are already in the global * variables. Just reuse them. */ doblock (); } else { dochar (c); } break; case 8: case 127: if (x > 0) { x = x - 1; editbuffer[(edit_buffer_y * 80) + x] = 0x0720; cgoto (); printf ("\e[0m"); putc (' ', stdout); ccolor (); cgoto (); } break; case 13: if (block == GET_BLOCK_COPY_DESTINATION) { copyblock(); block = NO_BLOCK; changed = 1; clear_status_line(); dorefresh(); } else { docr (); } break; case PAGEUP: ansipageup (); status (); break; case PAGEDOWN: ansipagedown (); status (); break; case HOME: if (x > 0) x = 0; else { ansihome (); edit_buffer_y = 0; y = 0; } status (); break; case INSERT: if (insert) insert = 0; else insert = 1; status (); break; case DELETE: dodelete (); break; case END: if (x < (EDIT_BUFFER_WIDTH - 1)) x = EDIT_BUFFER_WIDTH - 1; else { ansiend (); edit_buffer_y = EDIT_BUFFER_HEIGHT - 1; y = SCREEN_HEIGHT - 1; } status (); break; case CRSLEFT: if (x > 0) { newdir = 3; if (linedraw) dolinedraw (); x = x - 1; if ((text) && !(linedraw)) doattr (); printxy (); } else if (edit_buffer_y > 0) { x = 79; edit_buffer_y = edit_buffer_y - 1; if (y > 0) y = y - 1; else ansiscrollup (); newdir = 3; if (linedraw) dolinedraw (); if ((text) && !(linedraw)) doattr (); printxy (); } break; case CRSRIGHT: if (x < 79) { newdir = 4; if (linedraw) dolinedraw (); x = x + 1; if ((text) && !(linedraw)) doattr (); printxy (); } else if (edit_buffer_y < 999) { edit_buffer_y = edit_buffer_y + 1; x = 0; newdir = 4; if (y < 22) y = y + 1; else ansiscrolldown (); if (linedraw) dolinedraw (); if ((text) && !(linedraw)) doattr (); printxy (); } break; case CRSDOWN: if (edit_buffer_y < 999) { newdir = 2; if (linedraw) dolinedraw (); edit_buffer_y = edit_buffer_y + 1; if (y < 22) { y = y + 1; printxy (); } else { ansiscrolldown (); status (); } if ((text) && !(linedraw)) doattr (); } break; case CRSUP: if (edit_buffer_y > 0) { newdir = 1; if (linedraw) dolinedraw (); edit_buffer_y = edit_buffer_y - 1; if (y > 0) { y = y - 1; printxy (); } else { ansiscrollup (); status (); } if ((text) && !(linedraw)) doattr (); } break; case 256: /* F1 */ dochar (highascii[set][0]); break; case 257: /* F2 */ dochar (highascii[set][1]); break; case 258: /* F3 */ dochar (highascii[set][2]); break; case 259: /* F4 */ dochar (highascii[set][3]); break; case 260: /* F5 */ dochar (highascii[set][4]); break; case 256 + 17: /* F6 */ dochar (highascii[set][5]); break; case 256 + 18: /* F7 */ dochar (highascii[set][6]); break; case 256 + 19: /* F8 */ dochar (highascii[set][7]); break; case 256 + 20: /* F9 */ dochar (highascii[set][8]); break; case 256 + 21: /* F10 */ dochar (highascii[set][9]); break; case 256 + '<': /* alt-< */ if (set > 0) set = set - 1; status (); break; case 256 + '>': /* alt-> */ if (set < 14) set = set + 1; status (); break; case 256 + 'a': /* alt-a ? */ if (text) text = 0; else text = 1; status (); break; case 256 + 'b': /* alt-b block mode */ strcpy (statusline, "Use (L)ast block or move to upper left corner and " "press space."); block = GET_BLOCK_START_POSITION; linedraw = 0; text = 0; status (); break; case 256 + 'c': /* alt-c use character */ dochar (lastchar); break; case 256 + 'd': /* toggle line drawing mode */ if (linedraw) linedraw = 0; else linedraw = 1; status (); break; case 256 + 'e': /* erase page layer */ sprintf (input, "Erase page %d ? ", page + 1); doline (input); if (noyes ()) { clr (); ansihome (); fixvars (); } status (); break; case 256 + 'f': /* color selection */ printf ("\e[23;1H\e[0m\e[K\e[24;1H\e[K\e[25;1H\e[K\e[24;1H"); printf ("\e[0;37;40mSelect colors"); colorbar (); dorefresh (); break; case 256 + 'g': /* ? */ break; case 256 + 'h': /* help screen */ dohelp (); break; case 256 + 'i': /* insert line */ insertline (); break; case 256 + 'j': /* insert column */ insertcolumn (); break; case 256 + 'k': /* delete column */ deletecolumn (); break; case 256 + 'l': /* loadfile */ loadfile (); break; case 256 + 'm': /* ? */ break; case 256 + 'n': /* ? */ break; case 256 + 'o': /* ? */ break; case 256 + 'p': /* ? */ lastchar = editbuffer[(edit_buffer_y * 80) + x] & 0xFF; break; case 256 + 'q': /* ? */ break; case 256 + 'r': /* ? */ break; case 256 + 's': /* save file */ savefile (0); break; case 256 + 't': /* ? */ break; case 256 + 'u': /* alt-u */ attr = editbuffer[(edit_buffer_y * 80) + x]; attr = attr >> 8; fore = attr & 15; back = (attr >> 4) & 7; if (attr & 128) blink = 1; else blink = 0; status (); break; case 256 + 'v': /* ? */ break; case 256 + 'w': /* ? */ break; case 256 + 'x': /* exit */ doline ("Quit Duh DRAW ? "); if (noyes ()) { if (changed) savefile (0); return; } status (); break; case 256 + 'y': /* delete (yank line ) */ deleteline (); break; case 256 + 'z': /* ? */ break; case 256 + 23: /* shift F1 */ set = 0; status (); break; case 256 + 24: /* shift F2 */ set = 1; status (); break; case 256 + 25: /* shift F3 */ set = 2; status (); break; case 256 + 26: /* shift F4 */ set = 3; status (); break; case 256 + 28: /* shift F5 */ set = 4; status (); break; case 256 + 29: /* shift F6 */ set = 5; status (); break; case 256 + 31: /* shift F7 */ set = 6; status (); break; case 256 + 32: /* shift F8 */ set = 7; status (); break; case 256 + 33: /* shift F9 */ set = 8; status (); break; case 256 + 34: /* shift F10 */ set = 9; status (); break; case 32: if (block == GET_BLOCK_END_POSITION) { block_lower_right_y = edit_buffer_y; block_lower_right_x = x; doblock (); } else if (block == GET_BLOCK_START_POSITION) { block_upper_left_y = edit_buffer_y; block_upper_left_x = x; block = GET_BLOCK_END_POSITION; strcpy (statusline, "Move to lower right corner and press space."); status (); } else { dochar (32); } break; default: if ((c > 32) && (c < 128) && (block == 0)) { dochar (c); } break; } } } int main (int argc, char *argv[]) { int c; savetty (); initscr (); noecho (); /* shuttoff tty echoing */ nonl (); /* don't wait for carriage return */ cbreak (); printf ("\e(U"); /* set linux virtual console to IBM_PC graphics set */ clr (); /* clear buffer and screen */ strcpy (filename, ""); if (argc > 1) { if (strcmp (argv[1], "-help") == 0) dohelp (); else { strcpy (filename, argv[1]); readfile (); } } printf ("\e[0m\e[2J\e[1;34m"); printf ("%s", screendata); c = mygetchar (); fixvars (); editloop (); printf ("\e(B"); /* set unix character set */ printf ("\e[0m\e[2J\e[8;32H"); printf ("\e[0;1;32;40mThanks for using\e[0;1;37;40m\e[11;36HDuh Draw"); printf ("\e[13;39H\e[0;1;32;40mby\e[15;35H\e[1;37;40mBen Fowler\e[0m\n\n\r"); resetty (); endwin (); /* put the terminal back to normal */ return 0; }