diff options
Diffstat (limited to 'graphics/asymptote/gc/cord/tests')
-rw-r--r-- | graphics/asymptote/gc/cord/tests/cordtest.c | 351 | ||||
-rw-r--r-- | graphics/asymptote/gc/cord/tests/de.c | 640 | ||||
-rw-r--r-- | graphics/asymptote/gc/cord/tests/de_cmds.h | 31 | ||||
-rw-r--r-- | graphics/asymptote/gc/cord/tests/de_win.c | 387 | ||||
-rw-r--r-- | graphics/asymptote/gc/cord/tests/de_win.h | 97 | ||||
-rw-r--r-- | graphics/asymptote/gc/cord/tests/de_win.rc | 70 |
6 files changed, 1576 insertions, 0 deletions
diff --git a/graphics/asymptote/gc/cord/tests/cordtest.c b/graphics/asymptote/gc/cord/tests/cordtest.c new file mode 100644 index 0000000000..44df3e1b6c --- /dev/null +++ b/graphics/asymptote/gc/cord/tests/cordtest.c @@ -0,0 +1,351 @@ +/* + * Copyright (c) 1993-1994 by Xerox Corporation. All rights reserved. + * + * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED + * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. + * + * Permission is hereby granted to use or copy this program + * for any purpose, provided the above notices are retained on all copies. + * Permission to modify the code and to distribute modified code is granted, + * provided the above notices are retained, and a notice that the code was + * modified is included with the above copyright notice. + */ + +# include "gc.h" +# include "cord.h" + +# include <stdarg.h> +# include <string.h> +# include <stdio.h> +# include <stdlib.h> + +/* This is a very incomplete test of the cord package. It knows about */ +/* a few internals of the package (e.g. when C strings are returned) */ +/* that real clients shouldn't rely on. */ + +# define ABORT(string) \ + { fprintf(stderr, "FAILED: %s\n", string); abort(); } + +#if defined(CPPCHECK) +# undef CORD_iter +# undef CORD_next +# undef CORD_pos_fetch +# undef CORD_pos_to_cord +# undef CORD_pos_to_index +# undef CORD_pos_valid +# undef CORD_prev +#endif + +int count; + +int test_fn(char c, void * client_data) +{ + if (client_data != (void *)(GC_word)13) + ABORT("bad client data"); + if (count < 64*1024+1) { + if ((count & 1) == 0) { + if (c != 'b') ABORT("bad char"); + } else { + if (c != 'a') ABORT("bad char"); + } + count++; + return(0); + } else { + if (c != 'c') ABORT("bad char"); + count++; + return(1); + } +} + +char id_cord_fn(size_t i, void * client_data) +{ + if (client_data != 0) ABORT("id_cord_fn: bad client data"); + return((char)i); +} + +void test_basics(void) +{ + CORD x = CORD_from_char_star("ab"); + size_t i; + CORD y; + CORD_pos p; + + x = CORD_cat(x,x); + if (x == CORD_EMPTY) ABORT("CORD_cat(x,x) returned empty cord"); + if (!CORD_IS_STRING(x)) ABORT("short cord should usually be a string"); + if (strcmp(x, "abab") != 0) ABORT("bad CORD_cat result"); + + for (i = 1; i < 16; i++) { + x = CORD_cat(x,x); + } + x = CORD_cat(x,"c"); + if (CORD_len(x) != 128*1024+1) ABORT("bad length"); + + count = 0; + if (CORD_iter5(x, 64*1024-1, test_fn, CORD_NO_FN, + (void *)(GC_word)13) == 0) { + ABORT("CORD_iter5 failed"); + } + if (count != 64*1024 + 2) ABORT("CORD_iter5 failed"); + + count = 0; + CORD_set_pos(p, x, 64*1024-1); + while(CORD_pos_valid(p)) { + (void)test_fn(CORD_pos_fetch(p), (void *)(GC_word)13); + CORD_next(p); + } + if (count != 64*1024 + 2) ABORT("Position based iteration failed"); + + y = CORD_substr(x, 1023, 5); + if (!y) ABORT("CORD_substr returned NULL"); + if (!CORD_IS_STRING(y)) ABORT("short cord should usually be a string"); + if (strcmp(y, "babab") != 0) ABORT("bad CORD_substr result"); + + y = CORD_substr(x, 1024, 8); + if (!y) ABORT("CORD_substr returned NULL"); + if (!CORD_IS_STRING(y)) ABORT("short cord should usually be a string"); + if (strcmp(y, "abababab") != 0) ABORT("bad CORD_substr result"); + + y = CORD_substr(x, 128*1024-1, 8); + if (!y) ABORT("CORD_substr returned NULL"); + if (!CORD_IS_STRING(y)) ABORT("short cord should usually be a string"); + if (strcmp(y, "bc") != 0) ABORT("bad CORD_substr result"); + + x = CORD_balance(x); + if (CORD_len(x) != 128*1024+1) ABORT("bad length"); + + count = 0; + if (CORD_iter5(x, 64*1024-1, test_fn, CORD_NO_FN, + (void *)(GC_word)13) == 0) { + ABORT("CORD_iter5 failed"); + } + if (count != 64*1024 + 2) ABORT("CORD_iter5 failed"); + + y = CORD_substr(x, 1023, 5); + if (!y) ABORT("CORD_substr returned NULL"); + if (!CORD_IS_STRING(y)) ABORT("short cord should usually be a string"); + if (strcmp(y, "babab") != 0) ABORT("bad CORD_substr result"); + y = CORD_from_fn(id_cord_fn, 0, 13); + i = 0; + CORD_set_pos(p, y, i); + while(CORD_pos_valid(p)) { + char c = CORD_pos_fetch(p); + + if ((size_t)(unsigned char)c != i) + ABORT("Traversal of function node failed"); + CORD_next(p); + i++; + } + if (i != 13) ABORT("Bad apparent length for function node"); +# if defined(CPPCHECK) + /* TODO: Actually test these functions. */ + CORD_prev(p); + (void)CORD_pos_to_cord(p); + (void)CORD_pos_to_index(p); + (void)CORD_iter(CORD_EMPTY, test_fn, NULL); + (void)CORD_riter(CORD_EMPTY, test_fn, NULL); + CORD_dump(y); +# endif +} + +void test_extras(void) +{ +# define FNAME1 "cordtst1.tmp" /* short name (8+3) for portability */ +# define FNAME2 "cordtst2.tmp" + int i; + CORD y = "abcdefghijklmnopqrstuvwxyz0123456789"; + CORD x = "{}"; + CORD u, w, z; + FILE *f; + FILE *f1a, *f1b, *f2; + + w = CORD_cat(CORD_cat(y,y),y); + z = CORD_catn(3,y,y,y); + if (CORD_cmp(w,z) != 0) ABORT("CORD_catn comparison wrong"); + for (i = 1; i < 100; i++) { + x = CORD_cat(x, y); + } + z = CORD_balance(x); + if (CORD_cmp(x,z) != 0) ABORT("balanced string comparison wrong"); + if (CORD_cmp(x,CORD_cat(z, CORD_nul(13))) >= 0) ABORT("comparison 2"); + if (CORD_cmp(CORD_cat(x, CORD_nul(13)), z) <= 0) ABORT("comparison 3"); + if (CORD_cmp(x,CORD_cat(z, "13")) >= 0) ABORT("comparison 4"); + if ((f = fopen(FNAME1, "w")) == 0) ABORT("open failed"); + if (CORD_put(z,f) == EOF) ABORT("CORD_put failed"); + if (fclose(f) == EOF) ABORT("fclose failed"); + f1a = fopen(FNAME1, "rb"); + if (!f1a) ABORT("Unable to open " FNAME1); + w = CORD_from_file(f1a); + if (CORD_len(w) != CORD_len(z)) ABORT("file length wrong"); + if (CORD_cmp(w,z) != 0) ABORT("file comparison wrong"); + if (CORD_cmp(CORD_substr(w, 50*36+2, 36), y) != 0) + ABORT("file substr wrong"); + f1b = fopen(FNAME1, "rb"); + if (!f1b) ABORT("2nd open failed: " FNAME1); + z = CORD_from_file_lazy(f1b); + if (CORD_cmp(w,z) != 0) ABORT("File conversions differ"); + if (CORD_chr(w, 0, '9') != 37) ABORT("CORD_chr failed 1"); + if (CORD_chr(w, 3, 'a') != 38) ABORT("CORD_chr failed 2"); + if (CORD_rchr(w, CORD_len(w) - 1, '}') != 1) ABORT("CORD_rchr failed"); + x = y; + for (i = 1; i < 14; i++) { + x = CORD_cat(x,x); + } + if ((f = fopen(FNAME2, "w")) == 0) ABORT("2nd open failed"); +# ifdef __DJGPP__ + /* FIXME: DJGPP workaround. Why does this help? */ + if (fflush(f) != 0) ABORT("fflush failed"); +# endif + if (CORD_put(x,f) == EOF) ABORT("CORD_put failed"); + if (fclose(f) == EOF) ABORT("fclose failed"); + f2 = fopen(FNAME2, "rb"); + if (!f2) ABORT("Unable to open " FNAME2); + w = CORD_from_file(f2); + if (CORD_len(w) != CORD_len(x)) ABORT("file length wrong"); + if (CORD_cmp(w,x) != 0) ABORT("file comparison wrong"); + if (CORD_cmp(CORD_substr(w, 1000*36, 36), y) != 0) + ABORT("file substr wrong"); + if (strcmp(CORD_to_char_star(CORD_substr(w, 1000*36, 36)), y) != 0) + ABORT("char * file substr wrong"); + u = CORD_substr(w, 1000*36, 2); + if (!u) ABORT("CORD_substr returned NULL"); + if (strcmp(u, "ab") != 0) + ABORT("short file substr wrong"); + if (CORD_str(x,1,"9a") != 35) ABORT("CORD_str failed 1"); + if (CORD_str(x,0,"9abcdefghijk") != 35) ABORT("CORD_str failed 2"); + if (CORD_str(x,0,"9abcdefghijx") != CORD_NOT_FOUND) + ABORT("CORD_str failed 3"); + if (CORD_str(x,0,"9>") != CORD_NOT_FOUND) ABORT("CORD_str failed 4"); + /* Note: f1a, f1b, f2 handles are closed lazily by CORD library. */ + /* TODO: Propose and use CORD_fclose. */ + *(CORD volatile *)&w = CORD_EMPTY; + *(CORD volatile *)&z = CORD_EMPTY; + GC_gcollect(); +# ifndef GC_NO_FINALIZATION + GC_invoke_finalizers(); + /* Of course, this does not guarantee the files are closed. */ +# endif + if (remove(FNAME1) != 0) { + /* On some systems, e.g. OS2, this may fail if f1 is still open. */ + /* But we cannot call fclose as it might lead to double close. */ + fprintf(stderr, "WARNING: remove failed: " FNAME1 "\n"); + } +} + +int wrap_vprintf(CORD format, ...) +{ + va_list args; + int result; + + va_start(args, format); + result = CORD_vprintf(format, args); + va_end(args); + return result; +} + +int wrap_vfprintf(FILE * f, CORD format, ...) +{ + va_list args; + int result; + + va_start(args, format); + result = CORD_vfprintf(f, format, args); + va_end(args); + return result; +} + +#if defined(__DJGPP__) || defined(__STRICT_ANSI__) + /* snprintf is missing in DJGPP (v2.0.3) */ +#else +# if defined(_MSC_VER) +# if defined(_WIN32_WCE) + /* _snprintf is deprecated in WinCE */ +# define GC_SNPRINTF StringCchPrintfA +# else +# define GC_SNPRINTF _snprintf +# endif +# else +# define GC_SNPRINTF snprintf +# endif +#endif + +/* no static */ /* no const */ char *zu_format = (char*)"%zu"; + +void test_printf(void) +{ + CORD result; + char result2[200]; + long l = -1; + short s = (short)-1; + CORD x; + int res; + + if (CORD_sprintf(&result, "%7.2f%ln", 3.14159F, &l) != 7) + ABORT("CORD_sprintf failed 1"); + if (CORD_cmp(result, " 3.14") != 0) ABORT("CORD_sprintf goofed 1"); + if (l != 7) ABORT("CORD_sprintf goofed 2"); + if (CORD_sprintf(&result, "%-7.2s%hn%c%s", "abcd", &s, 'x', "yz") != 10) + ABORT("CORD_sprintf failed 2"); + if (CORD_cmp(result, "ab xyz") != 0) ABORT("CORD_sprintf goofed 3"); + if (s != 7) ABORT("CORD_sprintf goofed 4"); + x = "abcdefghij"; + x = CORD_cat(x,x); + x = CORD_cat(x,x); + x = CORD_cat(x,x); + if (CORD_sprintf(&result, "->%-120.78r!\n", x) != 124) + ABORT("CORD_sprintf failed 3"); +# ifdef GC_SNPRINTF + (void)GC_SNPRINTF(result2, sizeof(result2), "->%-120.78s!\n", + CORD_to_char_star(x)); +# else + (void)sprintf(result2, "->%-120.78s!\n", CORD_to_char_star(x)); +# endif + result2[sizeof(result2) - 1] = '\0'; + if (CORD_cmp(result, result2) != 0) ABORT("CORD_sprintf goofed 5"); + +# ifdef GC_SNPRINTF + /* Check whether "%zu" specifier is supported; pass the format */ + /* string via a variable to avoid a compiler warning if not. */ + res = GC_SNPRINTF(result2, sizeof(result2), zu_format, (size_t)0); +# else + res = sprintf(result2, zu_format, (size_t)0); +# endif + result2[sizeof(result2) - 1] = '\0'; + if (res == 1) /* is "%z" supported by printf? */ { + if (CORD_sprintf(&result, "%zu %zd 0x%0zx", + (size_t)123, (size_t)4567, (size_t)0x4abc) != 15) + ABORT("CORD_sprintf failed 5"); + if (CORD_cmp(result, "123 4567 0x4abc") != 0) + ABORT("CORD_sprintf goofed 5"); + } else { + (void)CORD_printf("printf lacks support of 'z' modifier\n"); + } + + /* TODO: Better test CORD_[v][f]printf. */ + (void)CORD_printf(CORD_EMPTY); + (void)wrap_vfprintf(stdout, CORD_EMPTY); + (void)wrap_vprintf(CORD_EMPTY); +} + +int main(void) +{ +# ifdef THINK_C + printf("cordtest:\n"); +# endif + GC_INIT(); +# ifndef NO_INCREMENTAL + GC_enable_incremental(); +# endif + if (GC_get_find_leak()) + printf("This test program is not designed for leak detection mode\n"); + test_basics(); + test_extras(); + test_printf(); + + GC_gcollect(); /* to close f2 before the file removal */ + if (remove(FNAME2) != 0) { + fprintf(stderr, "WARNING: remove failed: " FNAME2 "\n"); + } + CORD_fprintf(stdout, "SUCCEEDED\n"); + return(0); +} diff --git a/graphics/asymptote/gc/cord/tests/de.c b/graphics/asymptote/gc/cord/tests/de.c new file mode 100644 index 0000000000..2bdaa8e609 --- /dev/null +++ b/graphics/asymptote/gc/cord/tests/de.c @@ -0,0 +1,640 @@ +/* + * Copyright (c) 1993-1994 by Xerox Corporation. All rights reserved. + * + * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED + * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. + * + * Permission is hereby granted to use or copy this program + * for any purpose, provided the above notices are retained on all copies. + * Permission to modify the code and to distribute modified code is granted, + * provided the above notices are retained, and a notice that the code was + * modified is included with the above copyright notice. + */ + +/* + * A really simple-minded text editor based on cords. + * Things it does right: + * No size bounds. + * Unbounded undo. + * Shouldn't crash no matter what file you invoke it on (e.g. /vmunix) + * (Make sure /vmunix is not writable before you try this.) + * Scrolls horizontally. + * Things it does wrong: + * It doesn't handle tabs reasonably (use "expand" first). + * The command set is MUCH too small. + * The redisplay algorithm doesn't let curses do the scrolling. + * The rule for moving the window over the file is suboptimal. + */ + +#include <stdio.h> +#include <stdlib.h> /* for exit() */ + +#include "gc.h" +#include "cord.h" + +#ifdef THINK_C +#define MACINTOSH +#endif +#include <ctype.h> + +#if (defined(__BORLANDC__) || defined(__CYGWIN__) || defined(__MINGW32__) \ + || defined(__NT__) || defined(_WIN32)) && !defined(WIN32) + /* If this is DOS or win16, we'll fail anyway. */ +# define WIN32 +#endif + +#if defined(WIN32) +# ifndef WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN 1 +# endif +# define NOSERVICE +# include <windows.h> +# include "de_win.h" +#elif defined(MACINTOSH) +# include <console.h> +/* curses emulation. */ +# define initscr() +# define endwin() +# define nonl() +# define noecho() csetmode(C_NOECHO, stdout) +# define cbreak() csetmode(C_CBREAK, stdout) +# define refresh() +# define addch(c) putchar(c) +# define standout() cinverse(1, stdout) +# define standend() cinverse(0, stdout) +# define move(line,col) cgotoxy(col + 1, line + 1, stdout) +# define clrtoeol() ccleol(stdout) +# define de_error(s) { fprintf(stderr, s); getchar(); } +# define LINES 25 +# define COLS 80 +#else +# include <curses.h> +# include <unistd.h> /* for sleep() */ +# define de_error(s) { fprintf(stderr, s); sleep(2); } +#endif +#include "de_cmds.h" + +#if defined(CPPCHECK) +# define MACRO_BLKSTMT_BEGIN { +# define MACRO_BLKSTMT_END } +#else +# define MACRO_BLKSTMT_BEGIN do { +# define MACRO_BLKSTMT_END } while (0) +#endif + +#define OUT_OF_MEMORY MACRO_BLKSTMT_BEGIN \ + fprintf(stderr, "Out of memory\n"); \ + exit(3); \ + MACRO_BLKSTMT_END + +/* List of line number to position mappings, in descending order. */ +/* There may be holes. */ +typedef struct LineMapRep { + int line; + size_t pos; + struct LineMapRep * previous; +} * line_map; + +/* List of file versions, one per edit operation */ +typedef struct HistoryRep { + CORD file_contents; + struct HistoryRep * previous; + line_map map; /* Invalid for first record "now" */ +} * history; + +history now = 0; +CORD current; /* == now -> file_contents. */ +size_t current_len; /* Current file length. */ +line_map current_map = 0; /* Current line no. to pos. map */ +size_t current_map_size = 0; /* Number of current_map entries. */ + /* Not always accurate, but reset */ + /* by prune_map. */ +# define MAX_MAP_SIZE 3000 + +/* Current display position */ +int dis_line = 0; +int dis_col = 0; + +# define ALL -1 +# define NONE - 2 +int need_redisplay = 0; /* Line that needs to be redisplayed. */ + + +/* Current cursor position. Always within file. */ +int line = 0; +int col = 0; +size_t file_pos = 0; /* Character position corresponding to cursor. */ + +/* Invalidate line map for lines > i */ +void invalidate_map(int i) +{ + for (;;) { + if (NULL == current_map) exit(4); /* for CSA, should not happen */ + if (current_map -> line <= i) break; + current_map = current_map -> previous; + current_map_size--; + } +} + +/* Reduce the number of map entries to save space for huge files. */ +/* This also affects maps in histories. */ +void prune_map(void) +{ + line_map map = current_map; + int start_line = map -> line; + + current_map_size = 0; + do { + current_map_size++; + if (map -> line < start_line - LINES && map -> previous != 0) { + line_map pred = map -> previous -> previous; + + GC_PTR_STORE_AND_DIRTY(&map->previous, pred); + } + map = map -> previous; + } while (map != 0); +} + +/* Add mapping entry */ +void add_map(int line_arg, size_t pos) +{ + line_map new_map = GC_NEW(struct LineMapRep); + line_map cur_map; + + if (NULL == new_map) OUT_OF_MEMORY; + if (current_map_size >= MAX_MAP_SIZE) prune_map(); + new_map -> line = line_arg; + new_map -> pos = pos; + cur_map = current_map; + GC_PTR_STORE_AND_DIRTY(&new_map->previous, cur_map); + current_map = new_map; + current_map_size++; +} + +/* Return position of column *c of ith line in */ +/* current file. Adjust *c to be within the line.*/ +/* A 0 pointer is taken as 0 column. */ +/* Returns CORD_NOT_FOUND if i is too big. */ +/* Assumes i > dis_line. */ +size_t line_pos(int i, int *c) +{ + int j; + size_t cur; + line_map map = current_map; + + while (map -> line > i) map = map -> previous; + if (map -> line < i - 2) /* rebuild */ invalidate_map(i); + for (j = map -> line, cur = map -> pos; j < i;) { + cur = CORD_chr(current, cur, '\n'); + if (cur == current_len-1) return(CORD_NOT_FOUND); + cur++; + if (++j > current_map -> line) add_map(j, cur); + } + if (c != 0) { + size_t next = CORD_chr(current, cur, '\n'); + + if (next == CORD_NOT_FOUND) next = current_len - 1; + if (next < cur + *c) { + *c = (int)(next - cur); + } + cur += *c; + } + return(cur); +} + +void add_hist(CORD s) +{ + history new_file = GC_NEW(struct HistoryRep); + + if (NULL == new_file) OUT_OF_MEMORY; + new_file -> file_contents = current = s; + current_len = CORD_len(s); + new_file -> previous = now; + GC_END_STUBBORN_CHANGE(new_file); + if (now != NULL) { + now -> map = current_map; + GC_END_STUBBORN_CHANGE(now); + } + now = new_file; +} + +void del_hist(void) +{ + now = now -> previous; + current = now -> file_contents; + current_map = now -> map; + current_len = CORD_len(current); +} + +/* Current screen_contents; a dynamically allocated array of CORDs */ +CORD * screen = 0; +int screen_size = 0; + +# ifndef WIN32 +/* Replace a line in the curses stdscr. All control characters are */ +/* displayed as upper case characters in standout mode. This isn't */ +/* terribly appropriate for tabs. */ +void replace_line(int i, CORD s) +{ + CORD_pos p; +# if !defined(MACINTOSH) + size_t len = CORD_len(s); +# endif + + if (screen == 0 || LINES > screen_size) { + screen_size = LINES; + screen = (CORD *)GC_MALLOC(screen_size * sizeof(CORD)); + if (NULL == screen) OUT_OF_MEMORY; + } +# if !defined(MACINTOSH) + /* A gross workaround for an apparent curses bug: */ + if (i == LINES-1 && len == (unsigned)COLS) { + s = CORD_substr(s, 0, len - 1); + } +# endif + if (CORD_cmp(screen[i], s) != 0) { + move(i, 0); clrtoeol(); move(i,0); + + CORD_FOR (p, s) { + int c = CORD_pos_fetch(p) & 0x7f; + + if (iscntrl(c)) { + standout(); addch(c + 0x40); standend(); + } else { + addch(c); + } + } + GC_PTR_STORE_AND_DIRTY(screen + i, s); + } +} +#else +# define replace_line(i,s) invalidate_line(i) +#endif + +/* Return up to COLS characters of the line of s starting at pos, */ +/* returning only characters after the given column. */ +CORD retrieve_line(CORD s, size_t pos, unsigned column) +{ + CORD candidate = CORD_substr(s, pos, column + COLS); + /* avoids scanning very long lines */ + size_t eol = CORD_chr(candidate, 0, '\n'); + int len; + + if (eol == CORD_NOT_FOUND) eol = CORD_len(candidate); + len = (int)eol - (int)column; + if (len < 0) len = 0; + return(CORD_substr(s, pos + column, len)); +} + +# ifdef WIN32 +# define refresh(); + + CORD retrieve_screen_line(int i) + { + size_t pos; + + invalidate_map(dis_line + LINES); /* Prune search */ + pos = line_pos(dis_line + i, 0); + if (pos == CORD_NOT_FOUND) return(CORD_EMPTY); + return(retrieve_line(current, pos, dis_col)); + } +# endif + +/* Display the visible section of the current file */ +void redisplay(void) +{ + int i; + + invalidate_map(dis_line + LINES); /* Prune search */ + for (i = 0; i < LINES; i++) { + if (need_redisplay == ALL || need_redisplay == i) { + size_t pos = line_pos(dis_line + i, 0); + + if (pos == CORD_NOT_FOUND) break; + replace_line(i, retrieve_line(current, pos, dis_col)); + if (need_redisplay == i) goto done; + } + } + for (; i < LINES; i++) replace_line(i, CORD_EMPTY); +done: + refresh(); + need_redisplay = NONE; +} + +int dis_granularity; + +/* Update dis_line, dis_col, and dis_pos to make cursor visible. */ +/* Assumes line, col, dis_line, dis_pos are in bounds. */ +void normalize_display(void) +{ + int old_line = dis_line; + int old_col = dis_col; + + dis_granularity = 1; + if (LINES > 15 && COLS > 15) dis_granularity = 2; + while (dis_line > line) dis_line -= dis_granularity; + while (dis_col > col) dis_col -= dis_granularity; + while (line >= dis_line + LINES) dis_line += dis_granularity; + while (col >= dis_col + COLS) dis_col += dis_granularity; + if (old_line != dis_line || old_col != dis_col) { + need_redisplay = ALL; + } +} + +# if defined(WIN32) +# elif defined(MACINTOSH) +# define move_cursor(x,y) cgotoxy(x + 1, y + 1, stdout) +# else +# define move_cursor(x,y) move(y,x) +# endif + +/* Adjust display so that cursor is visible; move cursor into position */ +/* Update screen if necessary. */ +void fix_cursor(void) +{ + normalize_display(); + if (need_redisplay != NONE) redisplay(); + move_cursor(col - dis_col, line - dis_line); + refresh(); +# ifndef WIN32 + fflush(stdout); +# endif +} + +/* Make sure line, col, and dis_pos are somewhere inside file. */ +/* Recompute file_pos. Assumes dis_pos is accurate or past eof */ +void fix_pos(void) +{ + int my_col = col; + + if ((size_t)line > current_len) + line = (int)current_len; + file_pos = line_pos(line, &my_col); + if (file_pos == CORD_NOT_FOUND) { + for (line = current_map -> line, file_pos = current_map -> pos; + file_pos < current_len; + line++, file_pos = CORD_chr(current, file_pos, '\n') + 1); + line--; + file_pos = line_pos(line, &col); + } else { + col = my_col; + } +} + +#if defined(WIN32) +# define beep() Beep(1000 /* Hz */, 300 /* ms */) +#elif defined(MACINTOSH) +# define beep() SysBeep(1) +#else +/* + * beep() is part of some curses packages and not others. + * We try to match the type of the builtin one, if any. + */ + int beep(void) + { + putc('\007', stderr); + return(0); + } +#endif /* !WIN32 && !MACINTOSH */ + +# define NO_PREFIX -1 +# define BARE_PREFIX -2 +int repeat_count = NO_PREFIX; /* Current command prefix. */ + +int locate_mode = 0; /* Currently between 2 ^Ls */ +CORD locate_string = CORD_EMPTY; /* Current search string. */ + +char * arg_file_name; + +#ifdef WIN32 +/* Change the current position to whatever is currently displayed at */ +/* the given SCREEN coordinates. */ +void set_position(int c, int l) +{ + line = l + dis_line; + col = c + dis_col; + fix_pos(); + move_cursor(col - dis_col, line - dis_line); +} +#endif /* WIN32 */ + +/* Perform the command associated with character c. C may be an */ +/* integer > 256 denoting a windows command, one of the above control */ +/* characters, or another ASCII character to be used as either a */ +/* character to be inserted, a repeat count, or a search string, */ +/* depending on the current state. */ +void do_command(int c) +{ + int i; + int need_fix_pos; + FILE * out; + + if ( c == '\r') c = '\n'; + if (locate_mode) { + size_t new_pos; + + if (c == LOCATE) { + locate_mode = 0; + locate_string = CORD_EMPTY; + return; + } + locate_string = CORD_cat_char(locate_string, (char)c); + new_pos = CORD_str(current, file_pos - CORD_len(locate_string) + 1, + locate_string); + if (new_pos != CORD_NOT_FOUND) { + need_redisplay = ALL; + new_pos += CORD_len(locate_string); + for (;;) { + file_pos = line_pos(line + 1, 0); + if (file_pos > new_pos) break; + line++; + } + col = (int)(new_pos - line_pos(line, 0)); + file_pos = new_pos; + fix_cursor(); + } else { + locate_string = CORD_substr(locate_string, 0, + CORD_len(locate_string) - 1); + beep(); + } + return; + } + if (c == REPEAT) { + repeat_count = BARE_PREFIX; return; + } else if (c < 0x100 && isdigit(c)){ + if (repeat_count == BARE_PREFIX) { + repeat_count = c - '0'; return; + } else if (repeat_count != NO_PREFIX) { + repeat_count = 10 * repeat_count + c - '0'; return; + } + } + if (repeat_count == NO_PREFIX) repeat_count = 1; + if (repeat_count == BARE_PREFIX && (c == UP || c == DOWN)) { + repeat_count = LINES - dis_granularity; + } + if (repeat_count == BARE_PREFIX) repeat_count = 8; + need_fix_pos = 0; + for (i = 0; i < repeat_count; i++) { + switch(c) { + case LOCATE: + locate_mode = 1; + break; + case TOP: + line = col = 0; + file_pos = 0; + break; + case UP: + if (line != 0) { + line--; + need_fix_pos = 1; + } + break; + case DOWN: + line++; + need_fix_pos = 1; + break; + case LEFT: + if (col != 0) { + col--; file_pos--; + } + break; + case RIGHT: + if (CORD_fetch(current, file_pos) == '\n') break; + col++; file_pos++; + break; + case UNDO: + del_hist(); + need_redisplay = ALL; need_fix_pos = 1; + break; + case BS: + if (col == 0) { + beep(); + break; + } + col--; file_pos--; + /* FALLTHRU */ + case DEL: + if (file_pos == current_len-1) break; + /* Can't delete trailing newline */ + if (CORD_fetch(current, file_pos) == '\n') { + need_redisplay = ALL; need_fix_pos = 1; + } else { + need_redisplay = line - dis_line; + } + add_hist(CORD_cat( + CORD_substr(current, 0, file_pos), + CORD_substr(current, file_pos+1, current_len))); + invalidate_map(line); + break; + case WRITE: + { + CORD name = CORD_cat(CORD_from_char_star(arg_file_name), + ".new"); + + if ((out = fopen(CORD_to_const_char_star(name), "wb")) == NULL + || CORD_put(current, out) == EOF) { + de_error("Write failed\n"); + need_redisplay = ALL; + } else { + fclose(out); + } + } + break; + default: + { + CORD left_part = CORD_substr(current, 0, file_pos); + CORD right_part = CORD_substr(current, file_pos, current_len); + + add_hist(CORD_cat(CORD_cat_char(left_part, (char)c), + right_part)); + invalidate_map(line); + if (c == '\n') { + col = 0; line++; file_pos++; + need_redisplay = ALL; + } else { + col++; file_pos++; + need_redisplay = line - dis_line; + } + break; + } + } + } + if (need_fix_pos) fix_pos(); + fix_cursor(); + repeat_count = NO_PREFIX; +} + +/* OS independent initialization */ + +void generic_init(void) +{ + FILE * f; + CORD initial; + + if ((f = fopen(arg_file_name, "rb")) == NULL) { + initial = "\n"; + } else { + size_t len; + + initial = CORD_from_file(f); + len = CORD_len(initial); + if (0 == len || CORD_fetch(initial, len - 1) != '\n') { + initial = CORD_cat(initial, "\n"); + } + } + add_map(0,0); + add_hist(initial); + now -> map = current_map; + now -> previous = now; /* Can't back up further: beginning of the world */ + GC_END_STUBBORN_CHANGE(now); + need_redisplay = ALL; + fix_cursor(); +} + +#ifndef WIN32 + +int main(int argc, char **argv) +{ + int c; + void *buf; + +# if defined(MACINTOSH) + console_options.title = "\pDumb Editor"; + cshow(stdout); + argc = ccommand(&argv); +# endif + GC_set_find_leak(0); /* app is not for testing leak detection mode */ + GC_INIT(); +# ifndef NO_INCREMENTAL + GC_enable_incremental(); +# endif + + if (argc != 2) { + fprintf(stderr, "Usage: %s file\n", argv[0]); + fprintf(stderr, "Cursor keys: ^B(left) ^F(right) ^P(up) ^N(down)\n"); + fprintf(stderr, "Undo: ^U Write to <file>.new: ^W"); + fprintf(stderr, "Quit:^D Repeat count: ^R[n]\n"); + fprintf(stderr, "Top: ^T Locate (search, find): ^L text ^L\n"); + exit(1); + } + arg_file_name = argv[1]; + buf = GC_MALLOC_ATOMIC(8192); + if (NULL == buf) OUT_OF_MEMORY; + setvbuf(stdout, (char *)buf, _IOFBF, 8192); + initscr(); + noecho(); nonl(); cbreak(); + generic_init(); + while ((c = getchar()) != QUIT) { + if (c == EOF) break; + do_command(c); + } + move(LINES-1, 0); + clrtoeol(); + refresh(); + nl(); + echo(); + endwin(); + return 0; +} + +#endif /* !WIN32 */ diff --git a/graphics/asymptote/gc/cord/tests/de_cmds.h b/graphics/asymptote/gc/cord/tests/de_cmds.h new file mode 100644 index 0000000000..2a69594ef0 --- /dev/null +++ b/graphics/asymptote/gc/cord/tests/de_cmds.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 1994 by Xerox Corporation. All rights reserved. + * + * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED + * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. + * + * Permission is hereby granted to use or copy this program + * for any purpose, provided the above notices are retained on all copies. + * Permission to modify the code and to distribute modified code is granted, + * provided the above notices are retained, and a notice that the code was + * modified is included with the above copyright notice. + */ + +#ifndef DE_CMDS_H + +# define DE_CMDS_H + +# define UP 16 /* ^P */ +# define DOWN 14 /* ^N */ +# define LEFT 2 /* ^B */ +# define RIGHT 6 /* ^F */ +# define DEL 127 /* ^? */ +# define BS 8 /* ^H */ +# define UNDO 21 /* ^U */ +# define WRITE 23 /* ^W */ +# define QUIT 4 /* ^D */ +# define REPEAT 18 /* ^R */ +# define LOCATE 12 /* ^L */ +# define TOP 20 /* ^T */ + +#endif diff --git a/graphics/asymptote/gc/cord/tests/de_win.c b/graphics/asymptote/gc/cord/tests/de_win.c new file mode 100644 index 0000000000..45425ae6be --- /dev/null +++ b/graphics/asymptote/gc/cord/tests/de_win.c @@ -0,0 +1,387 @@ +/* + * Copyright (c) 1994 by Xerox Corporation. All rights reserved. + * + * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED + * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. + * + * Permission is hereby granted to use or copy this program + * for any purpose, provided the above notices are retained on all copies. + * Permission to modify the code and to distribute modified code is granted, + * provided the above notices are retained, and a notice that the code was + * modified is included with the above copyright notice. + */ + +/* + * The Windows specific part of de. + * This started as the generic Windows application template + * but significant parts didn't survive to the final version. + */ +#if defined(__BORLANDC__) || defined(__CYGWIN__) || defined(__MINGW32__) \ + || defined(__NT__) || defined(_WIN32) || defined(WIN32) + +#ifndef WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN 1 +#endif +#define NOSERVICE +#include <windows.h> + +#include <ctype.h> + +#include "gc.h" +#include "cord.h" +#include "de_cmds.h" +#include "de_win.h" + +int LINES = 0; +int COLS = 0; + +#define szAppName TEXT("DE") + +HWND hwnd; + +void de_error(const char *s) +{ + (void)MessageBoxA(hwnd, s, "Demonstration Editor", + MB_ICONINFORMATION | MB_OK); + InvalidateRect(hwnd, NULL, TRUE); +} + +int APIENTRY WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, + LPSTR command_line, int nCmdShow) +{ + MSG msg; + WNDCLASS wndclass; + HACCEL hAccel; + + GC_set_find_leak(0); + GC_INIT(); +# ifndef NO_INCREMENTAL + GC_enable_incremental(); +# endif +# if defined(CPPCHECK) + GC_noop1((GC_word)&WinMain); +# endif + + if (!hPrevInstance) + { + wndclass.style = CS_HREDRAW | CS_VREDRAW; + wndclass.lpfnWndProc = WndProc; + wndclass.cbClsExtra = 0; + wndclass.cbWndExtra = DLGWINDOWEXTRA; + wndclass.hInstance = hInstance; + wndclass.hIcon = LoadIcon (hInstance, szAppName); + wndclass.hCursor = LoadCursor (NULL, IDC_ARROW); + wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); + wndclass.lpszMenuName = TEXT("DE"); + wndclass.lpszClassName = szAppName; + + if (RegisterClass (&wndclass) == 0) { + de_error("RegisterClass error"); + return(0); + } + } + + /* Empirically, the command line does not include the command name ... + if (command_line != 0) { + while (isspace(*command_line)) command_line++; + while (*command_line != 0 && !isspace(*command_line)) command_line++; + while (isspace(*command_line)) command_line++; + } */ + + if (command_line == 0 || *command_line == 0) { + de_error("File name argument required"); + return( 0 ); + } else { + char *p = command_line; + + while (*p != 0 && !isspace(*(unsigned char *)p)) + p++; + arg_file_name = CORD_to_char_star( + CORD_substr(command_line, 0, p - command_line)); + } + + hwnd = CreateWindow (szAppName, + TEXT("Demonstration Editor"), + WS_OVERLAPPEDWINDOW | WS_CAPTION, /* Window style */ + CW_USEDEFAULT, 0, /* default pos. */ + CW_USEDEFAULT, 0, /* default width, height */ + NULL, /* No parent */ + NULL, /* Window class menu */ + hInstance, NULL); + if (hwnd == NULL) { + de_error("CreateWindow error"); + return(0); + } + + ShowWindow (hwnd, nCmdShow); + + hAccel = LoadAccelerators( hInstance, szAppName ); + + while (GetMessage (&msg, NULL, 0, 0)) + { + if( !TranslateAccelerator( hwnd, hAccel, &msg ) ) + { + TranslateMessage (&msg); + DispatchMessage (&msg); + } + } + return (int)msg.wParam; +} + +/* Return the argument with all control characters replaced by blanks. */ +char * plain_chars(char * text, size_t len) +{ + char * result = (char *)GC_MALLOC_ATOMIC(len + 1); + size_t i; + + if (NULL == result) return NULL; + for (i = 0; i < len; i++) { + if (iscntrl(((unsigned char *)text)[i])) { + result[i] = ' '; + } else { + result[i] = text[i]; + } + } + result[len] = '\0'; + return(result); +} + +/* Return the argument with all non-control-characters replaced by */ +/* blank, and all control characters c replaced by c + 64. */ +char * control_chars(char * text, size_t len) +{ + char * result = (char *)GC_MALLOC_ATOMIC(len + 1); + size_t i; + + if (NULL == result) return NULL; + for (i = 0; i < len; i++) { + if (iscntrl(((unsigned char *)text)[i])) { + result[i] = (char)(text[i] + 0x40); + } else { + result[i] = ' '; + } + } + result[len] = '\0'; + return(result); +} + +int char_width; +int char_height; + +void get_line_rect(int line_arg, int win_width, RECT * rectp) +{ + rectp -> top = line_arg * (LONG)char_height; + rectp -> bottom = rectp->top + char_height; + rectp -> left = 0; + rectp -> right = win_width; +} + +int caret_visible = 0; /* Caret is currently visible. */ + +int screen_was_painted = 0;/* Screen has been painted at least once. */ + +void update_cursor(void); + +INT_PTR CALLBACK AboutBoxCallback( HWND hDlg, UINT message, + WPARAM wParam, LPARAM lParam ) +{ + (void)lParam; + switch( message ) + { + case WM_INITDIALOG: + SetFocus( GetDlgItem( hDlg, IDOK ) ); + break; + + case WM_COMMAND: + switch( wParam ) + { + case IDOK: + EndDialog( hDlg, TRUE ); + break; + } + break; + + case WM_CLOSE: + EndDialog( hDlg, TRUE ); + return TRUE; + + } + return FALSE; +} + +LRESULT CALLBACK WndProc (HWND hwnd_arg, UINT message, + WPARAM wParam, LPARAM lParam) +{ + static HINSTANCE hInstance; + HDC dc; + PAINTSTRUCT ps; + RECT client_area; + RECT this_line; + RECT dummy; + TEXTMETRIC tm; + int i; + int id; + + switch (message) + { + case WM_CREATE: + hInstance = ( (LPCREATESTRUCT) lParam)->hInstance; + dc = GetDC(hwnd_arg); + SelectObject(dc, GetStockObject(SYSTEM_FIXED_FONT)); + GetTextMetrics(dc, &tm); + ReleaseDC(hwnd_arg, dc); + char_width = tm.tmAveCharWidth; + char_height = tm.tmHeight + tm.tmExternalLeading; + GetClientRect(hwnd_arg, &client_area); + COLS = (client_area.right - client_area.left)/char_width; + LINES = (client_area.bottom - client_area.top)/char_height; + generic_init(); + return(0); + + case WM_CHAR: + if (wParam == QUIT) { + SendMessage(hwnd_arg, WM_CLOSE, 0, 0L); + } else { + do_command((int)wParam); + } + return(0); + + case WM_SETFOCUS: + CreateCaret(hwnd_arg, NULL, char_width, char_height); + ShowCaret(hwnd_arg); + caret_visible = 1; + update_cursor(); + return(0); + + case WM_KILLFOCUS: + HideCaret(hwnd_arg); + DestroyCaret(); + caret_visible = 0; + return(0); + + case WM_LBUTTONUP: + { + unsigned xpos = LOWORD(lParam); /* From left */ + unsigned ypos = HIWORD(lParam); /* from top */ + + set_position(xpos / (unsigned)char_width, + ypos / (unsigned)char_height); + return(0); + } + + case WM_COMMAND: + id = LOWORD(wParam); + if (id & EDIT_CMD_FLAG) { + if (id & REPEAT_FLAG) do_command(REPEAT); + do_command(CHAR_CMD(id)); + return( 0 ); + } else { + switch(id) { + case IDM_FILEEXIT: + SendMessage(hwnd_arg, WM_CLOSE, 0, 0L); + return( 0 ); + + case IDM_HELPABOUT: + if( DialogBox( hInstance, TEXT("ABOUTBOX"), + hwnd_arg, AboutBoxCallback ) ) + InvalidateRect(hwnd_arg, NULL, TRUE); + return( 0 ); + case IDM_HELPCONTENTS: + de_error( + "Cursor keys: ^B(left) ^F(right) ^P(up) ^N(down)\n" + "Undo: ^U Write: ^W Quit:^D Repeat count: ^R[n]\n" + "Top: ^T Locate (search, find): ^L text ^L\n"); + return( 0 ); + } + } + break; + + case WM_CLOSE: + DestroyWindow(hwnd_arg); + return 0; + + case WM_DESTROY: + PostQuitMessage (0); + GC_win32_free_heap(); + return 0; + + case WM_PAINT: + dc = BeginPaint(hwnd_arg, &ps); + GetClientRect(hwnd_arg, &client_area); + COLS = (client_area.right - client_area.left)/char_width; + LINES = (client_area.bottom - client_area.top)/char_height; + SelectObject(dc, GetStockObject(SYSTEM_FIXED_FONT)); + for (i = 0; i < LINES; i++) { + get_line_rect(i, client_area.right, &this_line); + if (IntersectRect(&dummy, &this_line, &ps.rcPaint)) { + CORD raw_line = retrieve_screen_line(i); + size_t len = CORD_len(raw_line); + char * text = CORD_to_char_star(raw_line); + /* May contain embedded NULLs */ + char * plain = plain_chars(text, len); + char * blanks = CORD_to_char_star(CORD_chars(' ', + COLS - len)); + char * control = control_chars(text, len); + if (NULL == plain || NULL == control) + de_error("Out of memory!"); + +# define RED RGB(255,0,0) + + SetBkMode(dc, OPAQUE); + SetTextColor(dc, GetSysColor(COLOR_WINDOWTEXT)); + + if (plain != NULL) + TextOutA(dc, this_line.left, this_line.top, + plain, (int)len); + TextOutA(dc, this_line.left + (int)len * char_width, + this_line.top, + blanks, (int)(COLS - len)); + SetBkMode(dc, TRANSPARENT); + SetTextColor(dc, RED); + if (control != NULL) + TextOutA(dc, this_line.left, this_line.top, + control, (int)strlen(control)); + } + } + EndPaint(hwnd_arg, &ps); + screen_was_painted = 1; + return 0; + } + return DefWindowProc(hwnd_arg, message, wParam, lParam); +} + +int last_col; +int last_line; + +void move_cursor(int c, int l) +{ + last_col = c; + last_line = l; + + if (caret_visible) update_cursor(); +} + +void update_cursor(void) +{ + SetCaretPos(last_col * char_width, last_line * char_height); + ShowCaret(hwnd); +} + +void invalidate_line(int i) +{ + RECT line_r; + + if (!screen_was_painted) return; + /* Invalidating a rectangle before painting seems result in a */ + /* major performance problem. */ + get_line_rect(i, COLS*char_width, &line_r); + InvalidateRect(hwnd, &line_r, FALSE); +} + +#else + + extern int GC_quiet; + /* ANSI C doesn't allow translation units to be empty. */ + /* So we guarantee this one is nonempty. */ + +#endif /* !WIN32 */ diff --git a/graphics/asymptote/gc/cord/tests/de_win.h b/graphics/asymptote/gc/cord/tests/de_win.h new file mode 100644 index 0000000000..4a50780825 --- /dev/null +++ b/graphics/asymptote/gc/cord/tests/de_win.h @@ -0,0 +1,97 @@ +/* + * Copyright (c) 1994 by Xerox Corporation. All rights reserved. + * + * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED + * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. + * + * Permission is hereby granted to use or copy this program + * for any purpose, provided the above notices are retained on all copies. + * Permission to modify the code and to distribute modified code is granted, + * provided the above notices are retained, and a notice that the code was + * modified is included with the above copyright notice. + */ + +/* cord.h, de_cmds.h, and windows.h should be included before this. */ + +# define OTHER_FLAG 0x100 +# define EDIT_CMD_FLAG 0x200 +# define REPEAT_FLAG 0x400 + +# define CHAR_CMD(i) ((i) & 0xff) + +/* MENU: DE */ +#define IDM_FILESAVE (EDIT_CMD_FLAG + WRITE) +#define IDM_FILEEXIT (OTHER_FLAG + 1) +#define IDM_HELPABOUT (OTHER_FLAG + 2) +#define IDM_HELPCONTENTS (OTHER_FLAG + 3) + +#define IDM_EDITPDOWN (REPEAT_FLAG + EDIT_CMD_FLAG + DOWN) +#define IDM_EDITPUP (REPEAT_FLAG + EDIT_CMD_FLAG + UP) +#define IDM_EDITUNDO (EDIT_CMD_FLAG + UNDO) +#define IDM_EDITLOCATE (EDIT_CMD_FLAG + LOCATE) +#define IDM_EDITDOWN (EDIT_CMD_FLAG + DOWN) +#define IDM_EDITUP (EDIT_CMD_FLAG + UP) +#define IDM_EDITLEFT (EDIT_CMD_FLAG + LEFT) +#define IDM_EDITRIGHT (EDIT_CMD_FLAG + RIGHT) +#define IDM_EDITBS (EDIT_CMD_FLAG + BS) +#define IDM_EDITDEL (EDIT_CMD_FLAG + DEL) +#define IDM_EDITREPEAT (EDIT_CMD_FLAG + REPEAT) +#define IDM_EDITTOP (EDIT_CMD_FLAG + TOP) + + + + +/* Windows UI stuff */ + +LRESULT CALLBACK WndProc (HWND hwnd, UINT message, + WPARAM wParam, LPARAM lParam); + +/* Screen dimensions. Maintained by de_win.c. */ +extern int LINES; +extern int COLS; + +/* File being edited. */ +extern char * arg_file_name; + +/* Current display position in file. Maintained by de.c */ +extern int dis_line; +extern int dis_col; + +/* Current cursor position in file. */ +extern int line; +extern int col; + +/* + * Calls from de_win.c to de.c + */ + +CORD retrieve_screen_line(int i); + /* Get the contents of i'th screen line. */ + /* Relies on COLS. */ + +void set_position(int x, int y); + /* Set column, row. Upper left of window = (0,0). */ + +void do_command(int); + /* Execute an editor command. */ + /* Argument is a command character or one */ + /* of the IDM_ commands. */ + +void generic_init(void); + /* OS independent initialization */ + + +/* + * Calls from de.c to de_win.c + */ + +void move_cursor(int column, int line); + /* Physically move the cursor on the display, */ + /* so that it appears at */ + /* (column, line). */ + +void invalidate_line(int line); + /* Invalidate line i on the screen. */ + +void de_error(const char *s); + /* Display error message. */ diff --git a/graphics/asymptote/gc/cord/tests/de_win.rc b/graphics/asymptote/gc/cord/tests/de_win.rc new file mode 100644 index 0000000000..746a73dd22 --- /dev/null +++ b/graphics/asymptote/gc/cord/tests/de_win.rc @@ -0,0 +1,70 @@ +/* + * Copyright (c) 1991-1994 by Xerox Corporation. All rights reserved. + * + * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED + * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. + * + * Permission is hereby granted to use or copy this program + * for any purpose, provided the above notices are retained on all copies. + * Permission to modify the code and to distribute modified code is granted, + * provided the above notices are retained, and a notice that the code was + * modified is included with the above copyright notice. + */ + +#include "windows.h" +#include "de_cmds.h" +#include "de_win.h" + +ABOUTBOX DIALOG 19, 21, 163, 47 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "About Demonstration Text Editor" +BEGIN + LTEXT "Demonstration Text Editor", -1, 44, 8, 118, 8, WS_CHILD | WS_VISIBLE | WS_GROUP + PUSHBUTTON "OK", IDOK, 118, 27, 24, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP +END + +DE MENU +BEGIN + POPUP "&File" + BEGIN + MENUITEM "&Save\t^W", IDM_FILESAVE + MENUITEM "E&xit\t^D", IDM_FILEEXIT + END + + POPUP "&Edit" + BEGIN + MENUITEM "Page &Down\t^R^N", IDM_EDITPDOWN + MENUITEM "Page &Up\t^R^P", IDM_EDITPUP + MENUITEM "U&ndo\t^U", IDM_EDITUNDO + MENUITEM "&Locate\t^L ... ^L", IDM_EDITLOCATE + MENUITEM "D&own\t^N", IDM_EDITDOWN + MENUITEM "U&p\t^P", IDM_EDITUP + MENUITEM "Le&ft\t^B", IDM_EDITLEFT + MENUITEM "&Right\t^F", IDM_EDITRIGHT + MENUITEM "Delete &Backward\tBS", IDM_EDITBS + MENUITEM "Delete F&orward\tDEL", IDM_EDITDEL + MENUITEM "&Top\t^T", IDM_EDITTOP + END + + POPUP "&Help" + BEGIN + MENUITEM "&Contents", IDM_HELPCONTENTS + MENUITEM "&About...", IDM_HELPABOUT + END + + MENUITEM "Page_&Down", IDM_EDITPDOWN + MENUITEM "Page_&Up", IDM_EDITPUP +END + +DE ACCELERATORS +BEGIN + "^R", IDM_EDITREPEAT + "^N", IDM_EDITDOWN + "^P", IDM_EDITUP + "^L", IDM_EDITLOCATE + "^B", IDM_EDITLEFT + "^F", IDM_EDITRIGHT + "^T", IDM_EDITTOP + VK_DELETE, IDM_EDITDEL, VIRTKEY + VK_BACK, IDM_EDITBS, VIRTKEY +END |