From 88d50b5d7057d4f59c586c93ff290d0a39528f70 Mon Sep 17 00:00:00 2001 From: "Thomas E. Dickey" Date: Sun, 9 Mar 2008 00:57:07 +0000 Subject: [PATCH] ncurses 5.6 - patch 20080308 + start modifying test/rain.c for threading demo. + modify test/ncurses.c to make 'f' test accept the f/F/b/F/ toggles that the 'F' accepts. + modify test/worm.c to show trail in reverse-video when other threads are working concurrently. + fix a deadlock from improper nesting of mutexes for windowlist and window. --- NEWS | 11 +- dist.mk | 4 +- include/curses.h.in | 10 +- ncurses/base/use_window.c | 4 +- test/ncurses.c | 508 ++++++++++++++++++++++---------------- test/rain.c | 244 +++++++++++++----- test/worm.c | 15 +- 7 files changed, 510 insertions(+), 286 deletions(-) diff --git a/NEWS b/NEWS index 39613f05..6f9efb11 100644 --- a/NEWS +++ b/NEWS @@ -25,7 +25,7 @@ -- sale, use or other dealings in this Software without prior written -- -- authorization. -- ------------------------------------------------------------------------------- --- $Id: NEWS,v 1.1209 2008/03/01 20:02:41 tom Exp $ +-- $Id: NEWS,v 1.1213 2008/03/09 00:21:51 tom Exp $ ------------------------------------------------------------------------------- This is a log of changes that ncurses has gone through since Zeyd started @@ -45,6 +45,15 @@ See the AUTHORS file for the corresponding full names. Changes through 1.9.9e did not credit all contributions; it is not possible to add this information. +20080308 + + start modifying test/rain.c for threading demo. + + modify test/ncurses.c to make 'f' test accept the f/F/b/F/ toggles + that the 'F' accepts. + + modify test/worm.c to show trail in reverse-video when other threads + are working concurrently. + + fix a deadlock from improper nesting of mutexes for windowlist and + window. + 20080301 + fixes from 20080223 resolved issue with mutexes; change to use recursive mutexes to fix memory leak in delwin() as called from diff --git a/dist.mk b/dist.mk index b848f037..851936cf 100644 --- a/dist.mk +++ b/dist.mk @@ -25,7 +25,7 @@ # use or other dealings in this Software without prior written # # authorization. # ############################################################################## -# $Id: dist.mk,v 1.632 2008/03/01 16:53:24 tom Exp $ +# $Id: dist.mk,v 1.633 2008/03/02 15:19:41 tom Exp $ # Makefile for creating ncurses distributions. # # This only needs to be used directly as a makefile by developers, but @@ -37,7 +37,7 @@ SHELL = /bin/sh # These define the major/minor/patch versions of ncurses. NCURSES_MAJOR = 5 NCURSES_MINOR = 6 -NCURSES_PATCH = 20080301 +NCURSES_PATCH = 20080308 # We don't append the patch to the version, since this only applies to releases VERSION = $(NCURSES_MAJOR).$(NCURSES_MINOR) diff --git a/include/curses.h.in b/include/curses.h.in index b3379bf4..d1d3e8d2 100644 --- a/include/curses.h.in +++ b/include/curses.h.in @@ -32,7 +32,7 @@ * and: Thomas E. Dickey 1996-on * ****************************************************************************/ -/* $Id: curses.h.in,v 1.183 2008/01/19 20:03:48 tom Exp $ */ +/* $Id: curses.h.in,v 1.184 2008/03/08 21:03:48 tom Exp $ */ #ifndef __NCURSES_H #define __NCURSES_H @@ -1109,13 +1109,13 @@ extern NCURSES_EXPORT(int) wgetscrreg (const WINDOW *, int *, int *); /* generat #define wattr_set(win,a,p,opts) ((win)->_attrs = ((a) & ~A_COLOR), \ (win)->_color = (p), \ OK) -#define wattr_get(win,a,p,opts) ((void)((a) != 0 && (*(a) = (win)->_attrs)), \ - (void)((p) != 0 && (*(p) = (win)->_color)), \ +#define wattr_get(win,a,p,opts) ((void)((a) != (void *)0 && (*(a) = (win)->_attrs)), \ + (void)((p) != (void *)0 && (*(p) = (win)->_color)), \ OK) #else #define wattr_set(win,a,p,opts) ((win)->_attrs = (((a) & ~A_COLOR) | COLOR_PAIR(p)), OK) -#define wattr_get(win,a,p,opts) ((void)((a) != 0 && (*(a) = (win)->_attrs)), \ - (void)((p) != 0 && (*(p) = PAIR_NUMBER((win)->_attrs))), \ +#define wattr_get(win,a,p,opts) ((void)((a) != (void *)0 && (*(a) = (win)->_attrs)), \ + (void)((p) != (void *)0 && (*(p) = PAIR_NUMBER((win)->_attrs))), \ OK) #endif #endif /* NCURSES_OPAQUE */ diff --git a/ncurses/base/use_window.c b/ncurses/base/use_window.c index 4c9b1375..578dff3a 100644 --- a/ncurses/base/use_window.c +++ b/ncurses/base/use_window.c @@ -32,7 +32,7 @@ #include -MODULE_ID("$Id: use_window.c,v 1.3 2008/01/13 00:36:22 tom Exp $") +MODULE_ID("$Id: use_window.c,v 1.4 2008/03/02 11:42:37 tom Exp $") #ifdef USE_PTHREADS NCURSES_EXPORT(void) @@ -47,7 +47,6 @@ _nc_lock_window(WINDOW *win) break; } } - _nc_unlock_global(windowlist); } NCURSES_EXPORT(void) @@ -55,7 +54,6 @@ _nc_unlock_window(WINDOW *win) { WINDOWLIST *p; - _nc_lock_global(windowlist); for (p = _nc_windows; p != 0; p = p->next) { if (&(p->win) == win) { _nc_mutex_unlock(&(p->mutex_use_window)); diff --git a/test/ncurses.c b/test/ncurses.c index 0e724a65..7933e719 100644 --- a/test/ncurses.c +++ b/test/ncurses.c @@ -40,7 +40,7 @@ AUTHOR Author: Eric S. Raymond 1993 Thomas E. Dickey (beginning revision 1.27 in 1996). -$Id: ncurses.c,v 1.302 2008/02/23 23:07:28 tom Exp $ +$Id: ncurses.c,v 1.309 2008/03/08 20:57:09 tom Exp $ ***************************************************************************/ @@ -118,6 +118,8 @@ extern unsigned _nc_tracing; #endif +#define ToggleAcs(temp,real) temp = ((temp == real) ? 0 : real) + #define P(string) printw("%s\n", string) #define BLANK ' ' /* this is the background character */ @@ -2677,12 +2679,89 @@ wide_slk_test(void) * Alternate character-set stuff * ****************************************************************************/ +/* *INDENT-OFF* */ +static struct { + chtype attr; + const char *name; +} attrs_to_cycle[] = { + { A_NORMAL, "normal" }, + { A_BOLD, "bold" }, + { A_REVERSE, "reverse" }, + { A_UNDERLINE, "underline" }, +}; +/* *INDENT-ON* */ + +static bool +cycle_attr(int ch, unsigned *at_code, chtype *attr) +{ + bool result = TRUE; + + switch (ch) { + case 'v': + if ((*at_code += 1) >= SIZEOF(attrs_to_cycle)) + *at_code = 0; + break; + case 'V': + if (*at_code == 1) + *at_code = SIZEOF(attrs_to_cycle) - 1; + else + *at_code -= 1; + break; + default: + result = FALSE; + break; + } + if (result) + *attr = attrs_to_cycle[*at_code].attr; + return result; +} + +static bool +cycle_colors(int ch, int *fg, int *bg, short *pair) +{ + bool result = FALSE; + + if (use_colors) { + result = TRUE; + switch (ch) { + case 'F': + if ((*fg -= 1) < 0) + *fg = COLORS - 1; + break; + case 'f': + if ((*fg += 1) >= COLORS) + *fg = 0; + break; + case 'B': + if ((*bg -= 1) < 0) + *bg = COLORS - 1; + break; + case 'b': + if ((*bg += 1) >= COLORS) + *bg = 0; + break; + default: + result = FALSE; + break; + } + if (result) { + *pair = (*fg != COLOR_BLACK || *bg != COLOR_BLACK); + if (*pair != 0) { + *pair = 1; + if (init_pair(*pair, *fg, *bg) == ERR) { + result = FALSE; + } + } + } + } + return result; +} /* ISO 6429: codes 0x80 to 0x9f may be control characters that cause the * terminal to perform functions. The remaining codes can be graphic. */ static void -show_upper_chars(unsigned first) +show_upper_chars(unsigned first, int repeat, attr_t attr, short pair) { bool C1 = (first == 128); unsigned code; @@ -2697,27 +2776,33 @@ show_upper_chars(unsigned first) refresh(); for (code = first; code <= last; code++) { + int count = repeat; int row = 2 + ((code - first) % 16); int col = ((code - first) / 16) * COLS / 2; char tmp[80]; sprintf(tmp, "%3u (0x%x)", code, code); mvprintw(row, col, "%*s: ", COLS / 4, tmp); - if (C1) - nodelay(stdscr, TRUE); - echochar(code); - if (C1) { - /* (yes, this _is_ crude) */ - while ((reply = Getchar()) != ERR) { - addch(UChar(reply)); - napms(10); + + do { + if (C1) + nodelay(stdscr, TRUE); + echochar(code | attr | COLOR_PAIR(pair)); + if (C1) { + /* (yes, this _is_ crude) */ + while ((reply = Getchar()) != ERR) { + addch(UChar(reply)); + napms(10); + } + nodelay(stdscr, FALSE); } - nodelay(stdscr, FALSE); - } + } while (--count > 0); } } +#define PC_COLS 4 + static void -show_pc_chars(void) +show_pc_chars(int repeat, attr_t attr, short pair) { unsigned code; @@ -2728,35 +2813,41 @@ show_pc_chars(void) refresh(); for (code = 0; code < 16; ++code) { - mvprintw(2, (int) code * 3 + 8, "%X", code); + mvprintw(2, (int) code * PC_COLS + 8, "%X", code); } for (code = 0; code < 256; code++) { + int count = repeat; int row = 3 + (code / 16) + (code >= 128); - int col = 8 + (code % 16) * 3; + int col = 8 + (code % 16) * PC_COLS; if ((code % 16) == 0) mvprintw(row, 0, "0x%02x:", code); move(row, col); - switch (code) { - case '\n': - case '\r': - case '\b': - case '\f': - case '\033': - case 0x9b: - /* - * Skip the ones that do not work. - */ - break; - default: - addch(code | A_ALTCHARSET); - break; - } + do { + switch (code) { + case '\n': + case '\r': + case '\b': + case '\f': + case '\033': + case 0x9b: + /* + * Skip the ones that do not work. + */ + break; + default: + addch(code | A_ALTCHARSET | attr | COLOR_PAIR(pair)); + break; + } + } while (--count > 0); } } static void -show_box_chars(void) +show_box_chars(int repeat, attr_t attr, short pair) { + (void) repeat; + attr |= COLOR_PAIR(pair); + erase(); attron(A_BOLD); mvaddstr(0, 20, "Display of the ACS Line-Drawing Set"); @@ -2764,35 +2855,38 @@ show_box_chars(void) refresh(); box(stdscr, 0, 0); /* *INDENT-OFF* */ - mvhline(LINES / 2, 0, ACS_HLINE, COLS); - mvvline(0, COLS / 2, ACS_VLINE, LINES); - mvaddch(0, COLS / 2, ACS_TTEE); - mvaddch(LINES / 2, COLS / 2, ACS_PLUS); - mvaddch(LINES - 1, COLS / 2, ACS_BTEE); - mvaddch(LINES / 2, 0, ACS_LTEE); - mvaddch(LINES / 2, COLS - 1, ACS_RTEE); + mvhline(LINES / 2, 0, ACS_HLINE | attr, COLS); + mvvline(0, COLS / 2, ACS_VLINE | attr, LINES); + mvaddch(0, COLS / 2, ACS_TTEE | attr); + mvaddch(LINES / 2, COLS / 2, ACS_PLUS | attr); + mvaddch(LINES - 1, COLS / 2, ACS_BTEE | attr); + mvaddch(LINES / 2, 0, ACS_LTEE | attr); + mvaddch(LINES / 2, COLS - 1, ACS_RTEE | attr); /* *INDENT-ON* */ } static int -show_1_acs(int n, const char *name, chtype code) +show_1_acs(int n, int repeat, const char *name, chtype code) { const int height = 16; int row = 2 + (n % height); int col = (n / height) * COLS / 2; + mvprintw(row, col, "%*s : ", COLS / 4, name); - addch(code); + do { + addch(code); + } while (--repeat > 0); return n + 1; } static void -show_acs_chars(void) +show_acs_chars(int repeat, attr_t attr, short pair) /* display the ACS character set */ { int n; -#define BOTH(name) #name, name +#define BOTH(name) #name, (name | attr | COLOR_PAIR(pair)) erase(); attron(A_BOLD); @@ -2800,48 +2894,48 @@ show_acs_chars(void) attroff(A_BOLD); refresh(); - n = show_1_acs(0, BOTH(ACS_ULCORNER)); - n = show_1_acs(n, BOTH(ACS_URCORNER)); - n = show_1_acs(n, BOTH(ACS_LLCORNER)); - n = show_1_acs(n, BOTH(ACS_LRCORNER)); + n = show_1_acs(0, repeat, BOTH(ACS_ULCORNER)); + n = show_1_acs(n, repeat, BOTH(ACS_URCORNER)); + n = show_1_acs(n, repeat, BOTH(ACS_LLCORNER)); + n = show_1_acs(n, repeat, BOTH(ACS_LRCORNER)); - n = show_1_acs(n, BOTH(ACS_LTEE)); - n = show_1_acs(n, BOTH(ACS_RTEE)); - n = show_1_acs(n, BOTH(ACS_TTEE)); - n = show_1_acs(n, BOTH(ACS_BTEE)); + n = show_1_acs(n, repeat, BOTH(ACS_LTEE)); + n = show_1_acs(n, repeat, BOTH(ACS_RTEE)); + n = show_1_acs(n, repeat, BOTH(ACS_TTEE)); + n = show_1_acs(n, repeat, BOTH(ACS_BTEE)); - n = show_1_acs(n, BOTH(ACS_HLINE)); - n = show_1_acs(n, BOTH(ACS_VLINE)); + n = show_1_acs(n, repeat, BOTH(ACS_HLINE)); + n = show_1_acs(n, repeat, BOTH(ACS_VLINE)); /* * HPUX's ACS definitions are broken here. Just give up. */ #if !(defined(__hpux) && !defined(NCURSES_VERSION)) - n = show_1_acs(n, BOTH(ACS_LARROW)); - n = show_1_acs(n, BOTH(ACS_RARROW)); - n = show_1_acs(n, BOTH(ACS_UARROW)); - n = show_1_acs(n, BOTH(ACS_DARROW)); - - n = show_1_acs(n, BOTH(ACS_BLOCK)); - n = show_1_acs(n, BOTH(ACS_BOARD)); - n = show_1_acs(n, BOTH(ACS_LANTERN)); - n = show_1_acs(n, BOTH(ACS_BULLET)); - n = show_1_acs(n, BOTH(ACS_CKBOARD)); - n = show_1_acs(n, BOTH(ACS_DEGREE)); - n = show_1_acs(n, BOTH(ACS_DIAMOND)); - n = show_1_acs(n, BOTH(ACS_PLMINUS)); - n = show_1_acs(n, BOTH(ACS_PLUS)); - - n = show_1_acs(n, BOTH(ACS_GEQUAL)); - n = show_1_acs(n, BOTH(ACS_NEQUAL)); - n = show_1_acs(n, BOTH(ACS_LEQUAL)); - - n = show_1_acs(n, BOTH(ACS_STERLING)); - n = show_1_acs(n, BOTH(ACS_PI)); - n = show_1_acs(n, BOTH(ACS_S1)); - n = show_1_acs(n, BOTH(ACS_S3)); - n = show_1_acs(n, BOTH(ACS_S7)); - n = show_1_acs(n, BOTH(ACS_S9)); + n = show_1_acs(n, repeat, BOTH(ACS_LARROW)); + n = show_1_acs(n, repeat, BOTH(ACS_RARROW)); + n = show_1_acs(n, repeat, BOTH(ACS_UARROW)); + n = show_1_acs(n, repeat, BOTH(ACS_DARROW)); + + n = show_1_acs(n, repeat, BOTH(ACS_BLOCK)); + n = show_1_acs(n, repeat, BOTH(ACS_BOARD)); + n = show_1_acs(n, repeat, BOTH(ACS_LANTERN)); + n = show_1_acs(n, repeat, BOTH(ACS_BULLET)); + n = show_1_acs(n, repeat, BOTH(ACS_CKBOARD)); + n = show_1_acs(n, repeat, BOTH(ACS_DEGREE)); + n = show_1_acs(n, repeat, BOTH(ACS_DIAMOND)); + n = show_1_acs(n, repeat, BOTH(ACS_PLMINUS)); + n = show_1_acs(n, repeat, BOTH(ACS_PLUS)); + + n = show_1_acs(n, repeat, BOTH(ACS_GEQUAL)); + n = show_1_acs(n, repeat, BOTH(ACS_NEQUAL)); + n = show_1_acs(n, repeat, BOTH(ACS_LEQUAL)); + + n = show_1_acs(n, repeat, BOTH(ACS_STERLING)); + n = show_1_acs(n, repeat, BOTH(ACS_PI)); + n = show_1_acs(n, repeat, BOTH(ACS_S1)); + n = show_1_acs(n, repeat, BOTH(ACS_S3)); + n = show_1_acs(n, repeat, BOTH(ACS_S7)); + n = show_1_acs(n, repeat, BOTH(ACS_S9)); #endif } @@ -2853,6 +2947,14 @@ acs_display(void) const char *pch_kludge = ((term != 0 && strstr(term, "linux")) ? "p=PC, " : ""); + chtype attr = A_NORMAL; + int digit = 0; + int repeat = 1; + int fg = COLOR_BLACK; + int bg = COLOR_BLACK; + unsigned at_code = 0; + short pair = 0; + void (*last_show_acs) (int, attr_t, short) = 0; do { switch (c) { @@ -2860,29 +2962,77 @@ acs_display(void) Repaint(); break; case 'a': - show_acs_chars(); + ToggleAcs(last_show_acs, show_acs_chars); + break; + case 'p': + if (*pch_kludge) + ToggleAcs(last_show_acs, show_pc_chars); + else + beep(); break; case 'x': - show_box_chars(); + ToggleAcs(last_show_acs, show_box_chars); break; case '0': case '1': case '2': case '3': - show_upper_chars((unsigned) ((c - '0') * 32 + 128)); + digit = (c - '0'); + last_show_acs = 0; break; - case 'p': - show_pc_chars(); + case '-': + if (digit > 0) { + --digit; + last_show_acs = 0; + } else { + beep(); + } + break; + case '+': + if (digit < 3) { + ++digit; + last_show_acs = 0; + } else { + beep(); + } + break; + case '>': + if (repeat < (COLS / 4)) + ++repeat; + break; + case '<': + if (repeat > 1) + --repeat; break; default: - beep(); + if (cycle_attr(c, &at_code, &attr) + || cycle_colors(c, &fg, &bg, &pair)) { + break; + } else { + beep(); + } break; } + if (last_show_acs != 0) + last_show_acs(repeat, attr, pair); + else + show_upper_chars(digit * 32 + 128, repeat, attr, pair); + mvprintw(LINES - 3, 0, "Note: ANSI terminals may not display C1 characters."); mvprintw(LINES - 2, 0, - "Select: a=ACS, x=box, %s0=C1, 1,2,3=GR characters, ESC=quit", + "Select: a=ACS, x=box, %s0=C1, 1-3,+/- non-ASCII, repeat, ESC=quit", pch_kludge); + if (use_colors) { + mvprintw(LINES - 1, 0, + "v/V, f/F, b/B cycle through video attributes (%s) and color %d/%d.", + attrs_to_cycle[at_code].name, + fg, bg); + } else { + mvprintw(LINES - 1, 0, + "v/V cycles through video attributes (%s).", + attrs_to_cycle[at_code].name); + } refresh(); } while (!isQuit(c = Getchar())); @@ -2902,7 +3052,7 @@ merge_wide_attr(cchar_t *dst, const cchar_t *src, attr_t attr, short pair) *dst = *src; if (count > 0) { - if ((wch = typeMalloc(wchar_t, count)) != 0) { + if ((wch = typeMalloc(wchar_t, count + 1)) != 0) { if (getcchar(src, wch, &ignore_attr, &ignore_pair, 0) != ERR) { attr |= (ignore_attr & A_ALTCHARSET); setcchar(dst, wch, attr, pair, 0); @@ -2965,20 +3115,23 @@ show_upper_widechars(int first, int repeat, int space, attr_t attr, short pair) } static int -show_1_wacs(int n, const char *name, const cchar_t *code) +show_1_wacs(int n, int repeat, const char *name, const cchar_t *code) { const int height = 16; int row = 2 + (n % height); int col = (n / height) * COLS / 2; + mvprintw(row, col, "%*s : ", COLS / 4, name); - add_wchnstr(code, 1); + while (repeat-- >= 0) { + add_wch(code); + } return n + 1; } #define MERGE_ATTR(wch) merge_wide_attr(&temp, wch, attr, pair) static void -show_wacs_chars(attr_t attr, short pair) +show_wacs_chars(int repeat, attr_t attr, short pair) /* display the wide-ACS character set */ { cchar_t temp; @@ -2994,45 +3147,45 @@ show_wacs_chars(attr_t attr, short pair) attroff(A_BOLD); refresh(); - n = show_1_wacs(0, BOTH2(WACS_ULCORNER)); - n = show_1_wacs(n, BOTH2(WACS_URCORNER)); - n = show_1_wacs(n, BOTH2(WACS_LLCORNER)); - n = show_1_wacs(n, BOTH2(WACS_LRCORNER)); - - n = show_1_wacs(n, BOTH2(WACS_LTEE)); - n = show_1_wacs(n, BOTH2(WACS_RTEE)); - n = show_1_wacs(n, BOTH2(WACS_TTEE)); - n = show_1_wacs(n, BOTH2(WACS_BTEE)); - - n = show_1_wacs(n, BOTH2(WACS_HLINE)); - n = show_1_wacs(n, BOTH2(WACS_VLINE)); - - n = show_1_wacs(n, BOTH2(WACS_LARROW)); - n = show_1_wacs(n, BOTH2(WACS_RARROW)); - n = show_1_wacs(n, BOTH2(WACS_UARROW)); - n = show_1_wacs(n, BOTH2(WACS_DARROW)); - - n = show_1_wacs(n, BOTH2(WACS_BLOCK)); - n = show_1_wacs(n, BOTH2(WACS_BOARD)); - n = show_1_wacs(n, BOTH2(WACS_LANTERN)); - n = show_1_wacs(n, BOTH2(WACS_BULLET)); - n = show_1_wacs(n, BOTH2(WACS_CKBOARD)); - n = show_1_wacs(n, BOTH2(WACS_DEGREE)); - n = show_1_wacs(n, BOTH2(WACS_DIAMOND)); - n = show_1_wacs(n, BOTH2(WACS_PLMINUS)); - n = show_1_wacs(n, BOTH2(WACS_PLUS)); + n = show_1_wacs(0, repeat, BOTH2(WACS_ULCORNER)); + n = show_1_wacs(n, repeat, BOTH2(WACS_URCORNER)); + n = show_1_wacs(n, repeat, BOTH2(WACS_LLCORNER)); + n = show_1_wacs(n, repeat, BOTH2(WACS_LRCORNER)); + + n = show_1_wacs(n, repeat, BOTH2(WACS_LTEE)); + n = show_1_wacs(n, repeat, BOTH2(WACS_RTEE)); + n = show_1_wacs(n, repeat, BOTH2(WACS_TTEE)); + n = show_1_wacs(n, repeat, BOTH2(WACS_BTEE)); + + n = show_1_wacs(n, repeat, BOTH2(WACS_HLINE)); + n = show_1_wacs(n, repeat, BOTH2(WACS_VLINE)); + + n = show_1_wacs(n, repeat, BOTH2(WACS_LARROW)); + n = show_1_wacs(n, repeat, BOTH2(WACS_RARROW)); + n = show_1_wacs(n, repeat, BOTH2(WACS_UARROW)); + n = show_1_wacs(n, repeat, BOTH2(WACS_DARROW)); + + n = show_1_wacs(n, repeat, BOTH2(WACS_BLOCK)); + n = show_1_wacs(n, repeat, BOTH2(WACS_BOARD)); + n = show_1_wacs(n, repeat, BOTH2(WACS_LANTERN)); + n = show_1_wacs(n, repeat, BOTH2(WACS_BULLET)); + n = show_1_wacs(n, repeat, BOTH2(WACS_CKBOARD)); + n = show_1_wacs(n, repeat, BOTH2(WACS_DEGREE)); + n = show_1_wacs(n, repeat, BOTH2(WACS_DIAMOND)); + n = show_1_wacs(n, repeat, BOTH2(WACS_PLMINUS)); + n = show_1_wacs(n, repeat, BOTH2(WACS_PLUS)); #ifdef CURSES_WACS_ARRAY - n = show_1_wacs(n, BOTH2(WACS_GEQUAL)); - n = show_1_wacs(n, BOTH2(WACS_NEQUAL)); - n = show_1_wacs(n, BOTH2(WACS_LEQUAL)); - - n = show_1_wacs(n, BOTH2(WACS_STERLING)); - n = show_1_wacs(n, BOTH2(WACS_PI)); - n = show_1_wacs(n, BOTH2(WACS_S1)); - n = show_1_wacs(n, BOTH2(WACS_S3)); - n = show_1_wacs(n, BOTH2(WACS_S7)); - n = show_1_wacs(n, BOTH2(WACS_S9)); + n = show_1_wacs(n, repeat, BOTH2(WACS_GEQUAL)); + n = show_1_wacs(n, repeat, BOTH2(WACS_NEQUAL)); + n = show_1_wacs(n, repeat, BOTH2(WACS_LEQUAL)); + + n = show_1_wacs(n, repeat, BOTH2(WACS_STERLING)); + n = show_1_wacs(n, repeat, BOTH2(WACS_PI)); + n = show_1_wacs(n, repeat, BOTH2(WACS_S1)); + n = show_1_wacs(n, repeat, BOTH2(WACS_S3)); + n = show_1_wacs(n, repeat, BOTH2(WACS_S7)); + n = show_1_wacs(n, repeat, BOTH2(WACS_S9)); #endif } @@ -3041,10 +3194,11 @@ show_wacs_chars(attr_t attr, short pair) #define MERGE_ATTR(wch) merge_wide_attr(&temp, wch, attr, pair) static void -show_wbox_chars(attr_t attr, short pair) +show_wbox_chars(int repeat, attr_t attr, short pair) { cchar_t temp; + (void) repeat; erase(); attron(A_BOLD); mvaddstr(0, 20, "Display of the Wide-ACS Line-Drawing Set"); @@ -3086,10 +3240,11 @@ show_2_wacs(int n, const char *name, const char *code, attr_t attr, short pair) #define SHOW_UTF8(n, name, code) show_2_wacs(n, name, code, attr, pair) static void -show_utf8_chars(attr_t attr, short pair) +show_utf8_chars(int repeat, attr_t attr, short pair) { int n; + (void) repeat; erase(); attron(A_BOLD); mvaddstr(0, 20, "Display of the Wide-ACS Character Set"); @@ -3136,83 +3291,6 @@ show_utf8_chars(attr_t attr, short pair) /* *INDENT-ON* */ } -/* *INDENT-OFF* */ -static struct { - chtype attr; - const char *name; -} attrs_to_cycle[] = { - { A_NORMAL, "normal" }, - { A_BOLD, "bold" }, - { A_REVERSE, "reverse" }, - { A_UNDERLINE, "underline" }, -}; -/* *INDENT-ON* */ - -static bool -cycle_attr(int ch, unsigned *at_code, chtype *attr) -{ - bool result = TRUE; - - switch (ch) { - case 'v': - if ((*at_code += 1) >= SIZEOF(attrs_to_cycle)) - *at_code = 0; - break; - case 'V': - if (*at_code == 1) - *at_code = SIZEOF(attrs_to_cycle) - 1; - else - *at_code -= 1; - break; - default: - result = FALSE; - break; - } - if (result) - *attr = attrs_to_cycle[*at_code].attr; - return result; -} - -static bool -cycle_colors(int ch, int *fg, int *bg, short *pair) -{ - bool result = FALSE; - - if (use_colors) { - result = TRUE; - switch (ch) { - case 'F': - if ((*fg -= 1) < 0) - *fg = COLORS - 1; - break; - case 'f': - if ((*fg += 1) >= COLORS) - *fg = 0; - break; - case 'B': - if ((*bg -= 1) < 0) - *bg = COLORS - 1; - break; - case 'b': - if ((*bg += 1) < 0) - *bg = 0; - break; - default: - result = FALSE; - break; - } - if (result) { - *pair = (*fg != COLOR_BLACK || *bg != COLOR_BLACK); - if (*pair != 0) { - *pair = 1; - if (init_pair(*pair, *fg, *bg) == ERR) { - result = FALSE; - } - } - } - } - return result; -} /* display the wide-ACS character set */ static void @@ -3220,14 +3298,14 @@ wide_acs_display(void) { int c = 'a'; int digit = 0; - int repeat = 0; + int repeat = 1; int space = ' '; chtype attr = A_NORMAL; int fg = COLOR_BLACK; int bg = COLOR_BLACK; unsigned at_code = 0; short pair = 0; - void (*last_show_wacs) (attr_t, short) = 0; + void (*last_show_wacs) (int, attr_t, short) = 0; do { switch (c) { @@ -3235,27 +3313,31 @@ wide_acs_display(void) Repaint(); break; case 'a': - last_show_wacs = show_wacs_chars; + ToggleAcs(last_show_wacs, show_wacs_chars); break; case 'x': - last_show_wacs = show_wbox_chars; + ToggleAcs(last_show_wacs, show_wbox_chars); break; case 'u': - last_show_wacs = show_utf8_chars; + ToggleAcs(last_show_wacs, show_utf8_chars); break; default: if (c < 256 && isdigit(c)) { digit = (c - '0'); + last_show_wacs = 0; } else if (c == '+') { ++digit; + last_show_wacs = 0; } else if (c == '-' && digit > 0) { --digit; + last_show_wacs = 0; } else if (c == '>' && repeat < (COLS / 4)) { ++repeat; - } else if (c == '<' && repeat > 0) { + } else if (c == '<' && repeat > 1) { --repeat; } else if (c == '_') { space = (space == ' ') ? '_' : ' '; + last_show_wacs = 0; } else if (cycle_attr(c, &at_code, &attr) || cycle_colors(c, &fg, &bg, &pair)) { if (last_show_wacs != 0) @@ -3264,12 +3346,12 @@ wide_acs_display(void) beep(); break; } - last_show_wacs = 0; - show_upper_widechars(digit * 32 + 128, repeat, space, attr, pair); break; } if (last_show_wacs != 0) - last_show_wacs(attr, pair); + last_show_wacs(repeat, attr, pair); + else + show_upper_widechars(digit * 32 + 128, repeat, space, attr, pair); mvprintw(LINES - 3, 0, "Select: a WACS, x box, u UTF-8, 0-9,+/- non-ASCII, repeat, ESC=quit"); diff --git a/test/rain.c b/test/rain.c index f2c748ea..3f6c39fc 100644 --- a/test/rain.c +++ b/test/rain.c @@ -1,5 +1,5 @@ /**************************************************************************** - * Copyright (c) 1998-2002,2006 Free Software Foundation, Inc. * + * Copyright (c) 1998-2006,2008 Free Software Foundation, Inc. * * * * Permission is hereby granted, free of charge, to any person obtaining a * * copy of this software and associated documentation files (the * @@ -26,20 +26,65 @@ * authorization. * ****************************************************************************/ /* - * $Id: rain.c,v 1.22 2006/05/20 15:34:27 tom Exp $ + * $Id: rain.c,v 1.26 2008/03/09 00:17:09 tom Exp $ */ #include /* rain 11/3/1980 EPS/CITHEP */ -static float ranf(void); -static void onsig(int sig); +#ifdef USE_PTHREADS +#include +#endif + +WANT_USE_WINDOW(); + +#define MAX_DROP 5 + +struct DATA; + +typedef void (*DrawPart) (struct DATA *); + +typedef struct DATA { + int y, x; +#ifdef USE_PTHREADS + pthread_t thread; + DrawPart func; + int state; +#endif +} DATA; + +static void +onsig(int n GCC_UNUSED) +{ + curs_set(1); + endwin(); + ExitProgram(EXIT_FAILURE); +} + +static float +ranf(void) +{ + long r = (rand() & 077777); + return ((float) r / 32768.); +} + +static int +random_x(void) +{ + return (((float) (COLS - 4) * ranf()) + 2); +} + +static int +random_y(void) +{ + return (((float) (LINES - 4) * ranf()) + 2); +} static int next_j(int j) { if (j == 0) - j = 4; + j = MAX_DROP - 1; else --j; if (has_colors()) { @@ -52,15 +97,117 @@ next_j(int j) return j; } +static void +part1(DATA * drop) +{ + mvaddch(drop->y, drop->x, '.'); +} + +static void +part2(DATA * drop) +{ + mvaddch(drop->y, drop->x, 'o'); +} + +static void +part3(DATA * drop) +{ + mvaddch(drop->y, drop->x, 'O'); +} + +static void +part4(DATA * drop) +{ + mvaddch(drop->y - 1, drop->x, '-'); + mvaddstr(drop->y, drop->x - 1, "|.|"); + mvaddch(drop->y + 1, drop->x, '-'); +} + +static void +part5(DATA * drop) +{ + mvaddch(drop->y - 2, drop->x, '-'); + mvaddstr(drop->y - 1, drop->x - 1, "/ \\"); + mvaddstr(drop->y, drop->x - 2, "| O |"); + mvaddstr(drop->y + 1, drop->x - 1, "\\ /"); + mvaddch(drop->y + 2, drop->x, '-'); +} + +static void +part6(DATA * drop) +{ + mvaddch(drop->y - 2, drop->x, ' '); + mvaddstr(drop->y - 1, drop->x - 1, " "); + mvaddstr(drop->y, drop->x - 2, " "); + mvaddstr(drop->y + 1, drop->x - 1, " "); + mvaddch(drop->y + 2, drop->x, ' '); +} + +#ifdef USE_PTHREADS +static void +napsome(void) +{ + refresh(); + napms(60); +} + +/* + * This runs inside the mutex. + */ +static int +really_draw(WINDOW *win, void *arg) +{ + DATA *data = (DATA *) arg; + + (void) win; + next_j(data->state); + data->func(data); + return OK; +} + +static void +draw_part(void (*func) (DATA *), int state, DATA * data) +{ + data->func = func; + data->state = state; + use_window(stdscr, really_draw, (void *) data); + napsome(); +} + +static void * +draw_drop(void *arg) +{ + DATA mydata; + + mydata = *(DATA *) arg; /* make a copy of caller's data */ + + draw_part(part1, 0, &mydata); + draw_part(part2, 1, &mydata); + draw_part(part3, 2, &mydata); + draw_part(part4, 3, &mydata); + draw_part(part5, 4, &mydata); + draw_part(part6, 0, &mydata); + + return NULL; +} +#endif + +static int +get_input(void) +{ + int ch; + ch = USING_WINDOW(stdscr, wgetch); + return ch; +} + int -main( - int argc GCC_UNUSED, - char *argv[]GCC_UNUSED) +main(int argc GCC_UNUSED, + char *argv[]GCC_UNUSED) { - int x, y, j; - static int xpos[5], ypos[5]; - float r; - float c; + DATA drop; + DATA last[MAX_DROP]; + int j = 0; + bool done = FALSE; setlocale(LC_ALL, ""); @@ -82,52 +229,49 @@ main( curs_set(0); timeout(0); - r = (float) (LINES - 4); - c = (float) (COLS - 4); - for (j = 5; --j >= 0;) { - xpos[j] = (int) (c * ranf()) + 2; - ypos[j] = (int) (r * ranf()) + 2; + for (j = MAX_DROP; --j >= 0;) { + last[j].x = random_x(); + last[j].y = random_y(); } - for (j = 0;;) { - x = (int) (c * ranf()) + 2; - y = (int) (r * ranf()) + 2; + while (!done) { + drop.x = random_x(); + drop.y = random_y(); - mvaddch(y, x, '.'); +#ifdef USE_PTHREADS + if (pthread_create(&(drop.thread), NULL, draw_drop, &drop)) { + beep(); + done = TRUE; + continue; + } +#else + /* + * The non-threaded code draws parts of each drop on each loop. + */ + part1(&drop); - mvaddch(ypos[j], xpos[j], 'o'); + part2(&last[j]); j = next_j(j); - mvaddch(ypos[j], xpos[j], 'O'); + part3(&last[j]); j = next_j(j); - mvaddch(ypos[j] - 1, xpos[j], '-'); - mvaddstr(ypos[j], xpos[j] - 1, "|.|"); - mvaddch(ypos[j] + 1, xpos[j], '-'); + part4(&last[j]); j = next_j(j); - mvaddch(ypos[j] - 2, xpos[j], '-'); - mvaddstr(ypos[j] - 1, xpos[j] - 1, "/ \\"); - mvaddstr(ypos[j], xpos[j] - 2, "| O |"); - mvaddstr(ypos[j] + 1, xpos[j] - 1, "\\ /"); - mvaddch(ypos[j] + 2, xpos[j], '-'); + part5(&last[j]); j = next_j(j); - mvaddch(ypos[j] - 2, xpos[j], ' '); - mvaddstr(ypos[j] - 1, xpos[j] - 1, " "); - mvaddstr(ypos[j], xpos[j] - 2, " "); - mvaddstr(ypos[j] + 1, xpos[j] - 1, " "); - mvaddch(ypos[j] + 2, xpos[j], ' '); + part6(&last[j]); - xpos[j] = x; - ypos[j] = y; + last[j] = drop; +#endif - switch (getch()) { + switch (get_input()) { case ('q'): case ('Q'): - curs_set(1); - endwin(); - ExitProgram(EXIT_SUCCESS); + done = TRUE; + break; case 's': nodelay(stdscr, FALSE); break; @@ -136,26 +280,12 @@ main( break; #ifdef KEY_RESIZE case (KEY_RESIZE): - r = (float) (LINES - 4); - c = (float) (COLS - 4); break; #endif } napms(50); } -} - -static void -onsig(int n GCC_UNUSED) -{ curs_set(1); endwin(); - ExitProgram(EXIT_FAILURE); -} - -static float -ranf(void) -{ - long r = (rand() & 077777); - return ((float) r / 32768.); + ExitProgram(EXIT_SUCCESS); } diff --git a/test/worm.c b/test/worm.c index d78f9b96..e1c83d64 100644 --- a/test/worm.c +++ b/test/worm.c @@ -61,7 +61,7 @@ Options: traces will be dumped. The program stops and waits for one character of input at the beginning and end of the interval. - $Id: worm.c,v 1.56 2008/02/23 23:08:57 tom Exp $ + $Id: worm.c,v 1.57 2008/03/02 01:43:35 tom Exp $ */ #include @@ -109,6 +109,7 @@ static const char *field; static int length = 16, number = 3; static chtype trail = ' '; +static unsigned pending; #ifdef TRACE static int generation, trace_start, trace_end; #endif /* TRACE */ @@ -227,6 +228,8 @@ draw_worm(WINDOW *win, void *data) { WORM *w = (WORM *) data; const struct options *op; + unsigned mask = ~(1 << (w - worm)); + chtype attrs = w->attrs | ((mask & pending) ? A_REVERSE : 0); int x; int y; @@ -236,7 +239,7 @@ draw_worm(WINDOW *win, void *data) if ((x = w->xpos[h = w->head]) < 0) { wmove(win, y = w->ypos[h] = last_y, x = w->xpos[h] = 0); - waddch(win, w->attrs); + waddch(win, attrs); refs[y][x]++; } else { y = w->ypos[h]; @@ -299,7 +302,7 @@ draw_worm(WINDOW *win, void *data) if (y < 0) y = 0; - waddch(win, w->attrs); + waddch(win, attrs); w->ypos[h] = y; w->xpos[h] = x; @@ -311,9 +314,11 @@ draw_worm(WINDOW *win, void *data) #ifdef USE_PTHREADS static bool -quit_worm(void) +quit_worm(int bitnum) { + pending |= (1 << bitnum); napms(10); /* let the other thread(s) have a chance */ + pending &= ~(1 << bitnum); return quitting; } @@ -322,7 +327,7 @@ start_worm(void *arg) { unsigned long compare = 0; Trace(("start_worm")); - while (!quit_worm()) { + while (!quit_worm(((struct worm *) arg) - worm)) { while (compare < sequence) { ++compare; use_window(stdscr, draw_worm, arg); -- 2.44.0