From 6892b596222bdc5b2c0757a8f6cc79bcf2691d1a Mon Sep 17 00:00:00 2001 From: Frederic Culot Date: Sun, 21 Mar 2010 10:17:03 +0000 Subject: Avoid concurrent screen refreshes. --- src/calcurse.h | 5 +++- src/custom.c | 18 ++++++------- src/help.c | 4 +-- src/io.c | 12 ++++----- src/notify.c | 4 +-- src/utils.c | 21 ++++++++------- src/wins.c | 80 +++++++++++++++++++++++++++++++++++++++++++++++++++++----- 7 files changed, 107 insertions(+), 37 deletions(-) (limited to 'src') diff --git a/src/calcurse.h b/src/calcurse.h index fa18b56..6085f53 100644 --- a/src/calcurse.h +++ b/src/calcurse.h @@ -1,4 +1,4 @@ -/* $Id: calcurse.h,v 1.3 2010/03/21 09:21:07 culot Exp $ */ +/* $Id: calcurse.h,v 1.4 2010/03/21 10:17:03 culot Exp $ */ /* * Calcurse - text-based organizer @@ -897,6 +897,9 @@ void vars_init (struct conf *); /* wins.c */ extern struct window win[NBWINS]; +int wins_refresh (void); +int wins_wrefresh (WINDOW *); +int wins_doupdate (void); int wins_layout (void); void wins_set_layout (int); unsigned wins_sbar_width (void); diff --git a/src/custom.c b/src/custom.c index 007c71b..e6d547d 100755 --- a/src/custom.c +++ b/src/custom.c @@ -1,4 +1,4 @@ -/* $calcurse: custom.c,v 1.48 2010/03/21 09:21:07 culot Exp $ */ +/* $calcurse: custom.c,v 1.49 2010/03/21 10:17:03 culot Exp $ */ /* * Calcurse - text-based organizer @@ -250,7 +250,7 @@ custom_load_conf (struct conf *conf, int background) { status_mesg (mesg_line1, mesg_line2); wnoutrefresh (win[STA].p); - doupdate (); + wins_doupdate (); (void)keys_getch (win[STA].p); } var = CUSTOM_CONF_NOVARIABLE; @@ -432,7 +432,7 @@ custom_config_bar (void) wnoutrefresh (win[STA].p); wmove (win[STA].p, 0, 0); - doupdate (); + wins_doupdate (); } static void @@ -518,7 +518,7 @@ display_layout_config (struct window *lwin, int mark, int cursor, layout_selection_bar (); wnoutrefresh (win[STA].p); wnoutrefresh (lwin->p); - doupdate (); + wins_doupdate (); if (notify_bar ()) notify_update_bar (); } @@ -552,7 +552,7 @@ custom_layout_config (void) { case KEY_RESIZE: endwin (); - refresh (); + wins_refresh (); curs_set (0); need_reset = 1; break; @@ -611,7 +611,7 @@ custom_sidebar_config (void) binding_size = sizeof (binding) / sizeof (binding[0]); keys_display_bindings_bar (win[STA].p, binding, 0, binding_size); - doupdate (); + wins_doupdate (); while ((ch = keys_getch (win[STA].p)) != KEY_GENERIC_QUIT) { @@ -641,7 +641,7 @@ custom_sidebar_config (void) wins_update_border (); wins_update_panels (); keys_display_bindings_bar (win[STA].p, binding, 0, binding_size); - doupdate (); + wins_doupdate (); need_update = 0; } } @@ -828,7 +828,7 @@ display_color_config (struct window *cwin, int *mark_fore, int *mark_back, color_selection_bar (); wnoutrefresh (win[STA].p); wnoutrefresh (cwin->p); - doupdate (); + wins_doupdate (); if (notify_bar ()) notify_update_bar (); } @@ -861,7 +861,7 @@ custom_color_config (void) { case KEY_RESIZE: endwin (); - refresh (); + wins_refresh (); curs_set (0); need_reset = 1; break; diff --git a/src/help.c b/src/help.c index e4f7d48..f3b2209 100755 --- a/src/help.c +++ b/src/help.c @@ -1,4 +1,4 @@ -/* $calcurse: help.c,v 1.43 2010/03/20 10:54:45 culot Exp $ */ +/* $calcurse: help.c,v 1.44 2010/03/21 10:17:03 culot Exp $ */ /* * Calcurse - text-based organizer @@ -185,7 +185,7 @@ static void help_wins_reset (struct scrollwin *hwin) { endwin (); - refresh (); + wins_refresh (); curs_set (0); delwin (win[STA].p); help_wins_reinit (hwin); diff --git a/src/io.c b/src/io.c index 79ca3c0..271f0e6 100755 --- a/src/io.c +++ b/src/io.c @@ -1,4 +1,4 @@ -/* $calcurse: io.c,v 1.82 2010/03/21 09:21:07 culot Exp $ */ +/* $calcurse: io.c,v 1.83 2010/03/21 10:17:04 culot Exp $ */ /* * Calcurse - text-based organizer @@ -194,7 +194,7 @@ progress_bar (progress_bar_t type, int progress) mvwaddch (win[STA].p, 1, i, ' ' | A_REVERSE); custom_remove_attr (win[STA].p, ATTR_HIGHEST); wmove (win[STA].p, 0, 0); - wrefresh (win[STA].p); + wins_wrefresh (win[STA].p); (void)usleep (SLEEPTIME); #undef SLEEPTIME #undef NBFILES @@ -805,12 +805,12 @@ display_mark (void) custom_apply_attr (mwin, ATTR_HIGHEST); mvwprintw (mwin, 0, 0, "**"); - wrefresh (mwin); + wins_wrefresh (mwin); sleep (DISPLAY_TIME); mvwprintw (mwin, 0, 0, " "); - wrefresh (mwin); + wins_wrefresh (mwin); delwin (mwin); - doupdate (); + wins_doupdate (); } static pthread_mutex_t io_save_mutex = PTHREAD_MUTEX_INITIALIZER; @@ -1677,7 +1677,7 @@ io_export_bar (void) wnoutrefresh (win[STA].p); wmove (win[STA].p, 0, 0); - doupdate (); + wins_doupdate (); } /* Print a header to describe import log report format. */ diff --git a/src/notify.c b/src/notify.c index 1695faf..c36a2be 100755 --- a/src/notify.c +++ b/src/notify.c @@ -1,4 +1,4 @@ -/* $calcurse: notify.c,v 1.49 2010/03/20 10:54:47 culot Exp $ */ +/* $calcurse: notify.c,v 1.50 2010/03/21 10:17:04 culot Exp $ */ /* * Calcurse - text-based organizer @@ -318,7 +318,7 @@ notify_update_bar (void) wattroff (notify.win, A_UNDERLINE | A_REVERSE); custom_remove_attr (notify.win, ATTR_HIGHEST); - wrefresh (notify.win); + wins_wrefresh (notify.win); pthread_mutex_unlock (¬ify.mutex); } diff --git a/src/utils.c b/src/utils.c index ce976e6..0015c60 100755 --- a/src/utils.c +++ b/src/utils.c @@ -1,4 +1,4 @@ -/* $calcurse: utils.c,v 1.83 2010/03/20 10:54:49 culot Exp $ */ +/* $calcurse: utils.c,v 1.84 2010/03/21 10:17:04 culot Exp $ */ /* * Calcurse - text-based organizer @@ -57,7 +57,7 @@ exit_calcurse (int status) { notify_stop_main_thread (); clear (); - refresh (); + wins_refresh (); endwin (); ui_mode = UI_CMDLINE; was_interactive = 1; @@ -121,10 +121,10 @@ fatalbox (const char *errmsg) mvwprintw (errwin, 3, 1, reportmsg); mvwprintw (errwin, 5, (WINCOL - strlen (msg)) / 2, "%s", msg); custom_remove_attr (errwin, ATTR_HIGHEST); - wrefresh (errwin); + wins_wrefresh (errwin); (void)wgetch (errwin); delwin (errwin); - doupdate (); + wins_doupdate (); } void @@ -147,10 +147,10 @@ warnbox (const char *msg) wins_show (warnwin, label); mvwprintw (warnwin, 5, (WINCOL - strlen (displmsg)) / 2, "%s", displmsg); custom_remove_attr (warnwin, ATTR_HIGHEST); - wrefresh (warnwin); + wins_wrefresh (warnwin); (void)wgetch (warnwin); delwin (warnwin); - doupdate (); + wins_doupdate (); } /* @@ -206,8 +206,7 @@ popup (int pop_row, int pop_col, int pop_y, int pop_x, char *title, char *msg, mvwprintw (popup_win, pop_row - 2, pop_col - (strlen (any_key) + 1), "%s", any_key); custom_remove_attr (popup_win, ATTR_HIGHEST); - wrefresh (popup_win); - doupdate (); + wins_wrefresh (popup_win); return popup_win; } @@ -409,7 +408,7 @@ getstring (WINDOW *win, char *str, int l, int x, int y) } showstring (win, y, x, orig, len, newpos); - doupdate (); + wins_doupdate (); } *str = 0; custom_remove_attr (win, ATTR_HIGHEST); @@ -726,7 +725,7 @@ item_in_popup (char *saved_a_start, char *saved_a_end, char *msg, mvwprintw (pad, 0, margin_left, "%s", msg); wmove (win[STA].p, 0, 0); pnoutrefresh (pad, 0, 0, margin_top + 2, margin_left, padl, winw); - doupdate (); + wins_doupdate (); (void)wgetch (popup_win); delwin (pad); delwin (popup_win); @@ -813,7 +812,7 @@ print_bool_option_incolor (WINDOW *win, unsigned option, int pos_y, int pos_x) mvwprintw (win, pos_y, pos_x, "%s", option_value); custom_remove_attr (win, color); wnoutrefresh (win); - doupdate (); + wins_doupdate (); } /* diff --git a/src/wins.c b/src/wins.c index 8cdd9da..cfe1050 100755 --- a/src/wins.c +++ b/src/wins.c @@ -1,4 +1,4 @@ -/* $calcurse: wins.c,v 1.31 2010/03/21 09:21:07 culot Exp $ */ +/* $calcurse: wins.c,v 1.32 2010/03/21 10:17:04 culot Exp $ */ /* * Calcurse - text-based organizer @@ -51,6 +51,74 @@ static unsigned sbarwidth; static enum win slctd_win; static int layout; +/* + * The screen_mutex mutex and wins_refresh(), wins_wrefresh(), wins_doupdate() + * functions are used to prevent concurrent updates of the screen. + * It was observed that the display could get screwed up when mulitple threads + * tried to refresh the screen at the same time. + * + * Note (2010-03-21): + * Since recent versions of ncurses (5.7), rudimentary support for threads are + * available (use_screen(), use_window() for instance - see curs_threads(3)), + * but to remain compatible with earlier versions, it was chosen to rely on a + * screen-level mutex instead. + */ +static pthread_mutex_t screen_mutex = PTHREAD_MUTEX_INITIALIZER; + +static unsigned +screen_acquire (void) +{ + if (pthread_mutex_lock (&screen_mutex) != 0) + return 0; + else + return 1; +} + +static void +screen_release (void) +{ + (void)pthread_mutex_unlock (&screen_mutex); +} + +int +wins_refresh (void) +{ + int rc; + + if (!screen_acquire ()) + return ERR; + rc = refresh (); + screen_release (); + + return rc; +} + +int +wins_wrefresh (WINDOW *win) +{ + int rc; + + if (!win || !screen_acquire ()) + return ERR; + rc = wrefresh (win); + screen_release (); + + return rc; +} + +int +wins_doupdate (void) +{ + int rc; + + if (!screen_acquire ()) + return ERR; + rc = doupdate (); + screen_release (); + + return rc; +} + /* Get the current layout. */ int wins_layout (void) @@ -236,7 +304,7 @@ wins_scrollwin_display (struct scrollwin *sw) wnoutrefresh (sw->win.p); pnoutrefresh (sw->pad.p, sw->first_visible_line, 0, sw->pad.y, sw->pad.x, sw->win.h - sw->pad.y + 1, sw->win.w - sw->win.x); - doupdate (); + wins_doupdate (); } void @@ -520,7 +588,7 @@ wins_update (void) if (notify_bar ()) notify_update_bar (); wmove (win[STA].p, 0, 0); - doupdate (); + wins_doupdate (); } /* Reset the screen, needed when resizing terminal for example. */ @@ -528,7 +596,7 @@ void wins_reset (void) { endwin (); - refresh (); + wins_refresh (); curs_set (0); wins_reinit (); wins_update (); @@ -559,13 +627,13 @@ wins_launch_external (const char *file, const char *cmd) endwin (); ui_mode = UI_CMDLINE; clear (); - refresh (); + wins_refresh (); (void)system (p); reset_prog_mode (); clearok (curscr, TRUE); curs_set (0); ui_mode = UI_CURSES; - refresh (); + wins_refresh (); if (notify_bar ()) notify_start_main_thread (); mem_free (p); -- cgit v1.2.3-54-g00ecf