diff options
Diffstat (limited to 'src/nvim/ui_bridge.c')
| -rw-r--r-- | src/nvim/ui_bridge.c | 305 | 
1 files changed, 29 insertions, 276 deletions
| diff --git a/src/nvim/ui_bridge.c b/src/nvim/ui_bridge.c index 9f780663ac..a8bbeea035 100644 --- a/src/nvim/ui_bridge.c +++ b/src/nvim/ui_bridge.c @@ -1,3 +1,6 @@ +// This is an open source non-commercial project. Dear PVS-Studio, please check +// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com +  // UI wrapper that sends requests to the UI thread.  // Used by the built-in TUI and libnvim-based UIs. @@ -21,46 +24,29 @@  #define UI(b) (((UIBridgeData *)b)->ui) -#if MIN_LOG_LEVEL <= DEBUG_LOG_LEVEL -static size_t        uilog_seen = 0; -static argv_callback uilog_event = NULL; -#define UI_CALL(ui, name, argc, ...) \ -  do { \ -    if (uilog_event == ui_bridge_##name##_event) { \ -      uilog_seen++; \ -    } else { \ -      if (uilog_seen > 0) { \ -        DLOG("UI bridge: ...%zu times", uilog_seen); \ -      } \ -      DLOG("UI bridge: " STR(name)); \ -      uilog_seen = 0; \ -      uilog_event = ui_bridge_##name##_event; \ -    } \ -    ((UIBridgeData *)ui)->scheduler( \ -        event_create(1, ui_bridge_##name##_event, argc, __VA_ARGS__), UI(ui)); \ -  } while (0) -#else  // Schedule a function call on the UI bridge thread. -#define UI_CALL(ui, name, argc, ...) \ +#define UI_BRIDGE_CALL(ui, name, argc, ...) \    ((UIBridgeData *)ui)->scheduler( \ -      event_create(1, ui_bridge_##name##_event, argc, __VA_ARGS__), UI(ui)) -#endif +      event_create(ui_bridge_##name##_event, argc, __VA_ARGS__), UI(ui)) + +#define INT2PTR(i) ((void *)(intptr_t)i) +#define PTR2INT(p) ((Integer)(intptr_t)p) -#define INT2PTR(i) ((void *)(uintptr_t)i) -#define PTR2INT(p) ((int)(uintptr_t)p) +#ifdef INCLUDE_GENERATED_DECLARATIONS +# include "ui_events_bridge.generated.h" +#endif  UI *ui_bridge_attach(UI *ui, ui_main_fn ui_main, event_scheduler scheduler)  {    UIBridgeData *rv = xcalloc(1, sizeof(UIBridgeData));    rv->ui = ui;    rv->bridge.rgb = ui->rgb; -  rv->bridge.pum_external = ui->pum_external;    rv->bridge.stop = ui_bridge_stop;    rv->bridge.resize = ui_bridge_resize;    rv->bridge.clear = ui_bridge_clear;    rv->bridge.eol_clear = ui_bridge_eol_clear;    rv->bridge.cursor_goto = ui_bridge_cursor_goto; -  rv->bridge.cursor_style_set = ui_bridge_cursor_style_set; +  rv->bridge.mode_info_set = ui_bridge_mode_info_set;    rv->bridge.update_menu = ui_bridge_update_menu;    rv->bridge.busy_start = ui_bridge_busy_start;    rv->bridge.busy_stop = ui_bridge_busy_stop; @@ -73,15 +59,18 @@ UI *ui_bridge_attach(UI *ui, ui_main_fn ui_main, event_scheduler scheduler)    rv->bridge.put = ui_bridge_put;    rv->bridge.bell = ui_bridge_bell;    rv->bridge.visual_bell = ui_bridge_visual_bell; -  rv->bridge.update_fg = ui_bridge_update_fg; -  rv->bridge.update_bg = ui_bridge_update_bg; -  rv->bridge.update_sp = ui_bridge_update_sp; +  rv->bridge.default_colors_set = ui_bridge_default_colors_set;    rv->bridge.flush = ui_bridge_flush;    rv->bridge.suspend = ui_bridge_suspend;    rv->bridge.set_title = ui_bridge_set_title;    rv->bridge.set_icon = ui_bridge_set_icon; +  rv->bridge.option_set = ui_bridge_option_set;    rv->scheduler = scheduler; +  for (UIExtension i = 0; (int)i < kUIExtCount; i++) { +    rv->bridge.ui_ext[i] = ui->ui_ext[i]; +  } +    rv->ui_main = ui_main;    uv_mutex_init(&rv->mutex);    uv_cond_init(&rv->cond); @@ -92,6 +81,7 @@ UI *ui_bridge_attach(UI *ui, ui_main_fn ui_main, event_scheduler scheduler)      abort();    } +  // Suspend the main thread until CONTINUE is called by the UI thread.    while (!rv->ready) {      uv_cond_wait(&rv->cond, &rv->mutex);    } @@ -116,22 +106,25 @@ static void ui_thread_run(void *data)  static void ui_bridge_stop(UI *b)  { +  // Detach brigde first, so that "stop" is the last event the TUI loop +  // receives from the main thread. #8041 +  ui_detach_impl(b);    UIBridgeData *bridge = (UIBridgeData *)b;    bool stopped = bridge->stopped = false; -  UI_CALL(b, stop, 1, b); +  UI_BRIDGE_CALL(b, stop, 1, b);    for (;;) {      uv_mutex_lock(&bridge->mutex);      stopped = bridge->stopped;      uv_mutex_unlock(&bridge->mutex); -    if (stopped) { +    if (stopped) {  // -V547        break;      } -    loop_poll_events(&main_loop, 10); +    loop_poll_events(&main_loop, 10);  // Process one event.    }    uv_thread_join(&bridge->ui_thread);    uv_mutex_destroy(&bridge->mutex);    uv_cond_destroy(&bridge->cond); -  ui_detach_impl(b); +  xfree(bridge->ui);  // Threads joined, now safe to free UI container. #7922    xfree(b);  }  static void ui_bridge_stop_event(void **argv) @@ -140,153 +133,11 @@ static void ui_bridge_stop_event(void **argv)    ui->stop(ui);  } -static void ui_bridge_resize(UI *b, int width, int height) -{ -  UI_CALL(b, resize, 3, b, INT2PTR(width), INT2PTR(height)); -} -static void ui_bridge_resize_event(void **argv) -{ -  UI *ui = UI(argv[0]); -  ui->resize(ui, PTR2INT(argv[1]), PTR2INT(argv[2])); -} - -static void ui_bridge_clear(UI *b) -{ -  UI_CALL(b, clear, 1, b); -} -static void ui_bridge_clear_event(void **argv) -{ -  UI *ui = UI(argv[0]); -  ui->clear(ui); -} - -static void ui_bridge_eol_clear(UI *b) -{ -  UI_CALL(b, eol_clear, 1, b); -} -static void ui_bridge_eol_clear_event(void **argv) -{ -  UI *ui = UI(argv[0]); -  ui->eol_clear(ui); -} - -static void ui_bridge_cursor_goto(UI *b, int row, int col) -{ -  UI_CALL(b, cursor_goto, 3, b, INT2PTR(row), INT2PTR(col)); -} -static void ui_bridge_cursor_goto_event(void **argv) -{ -  UI *ui = UI(argv[0]); -  ui->cursor_goto(ui, PTR2INT(argv[1]), PTR2INT(argv[2])); -} - -static void ui_bridge_cursor_style_set(UI *b, bool enabled, Dictionary styles) -{ -  bool *enabledp = xmalloc(sizeof(*enabledp)); -  Object *stylesp = xmalloc(sizeof(*stylesp)); -  *enabledp = enabled; -  *stylesp = copy_object(DICTIONARY_OBJ(styles)); -  UI_CALL(b, cursor_style_set, 3, b, enabledp, stylesp); -} -static void ui_bridge_cursor_style_set_event(void **argv) -{ -  UI *ui = UI(argv[0]); -  bool *enabled = argv[1]; -  Object *styles = argv[2]; -  ui->cursor_style_set(ui, *enabled, styles->data.dictionary); -  xfree(enabled); -  api_free_object(*styles); -  xfree(styles); -} - -static void ui_bridge_update_menu(UI *b) -{ -  UI_CALL(b, update_menu, 1, b); -} -static void ui_bridge_update_menu_event(void **argv) -{ -  UI *ui = UI(argv[0]); -  ui->update_menu(ui); -} - -static void ui_bridge_busy_start(UI *b) -{ -  UI_CALL(b, busy_start, 1, b); -} -static void ui_bridge_busy_start_event(void **argv) -{ -  UI *ui = UI(argv[0]); -  ui->busy_start(ui); -} - -static void ui_bridge_busy_stop(UI *b) -{ -  UI_CALL(b, busy_stop, 1, b); -} -static void ui_bridge_busy_stop_event(void **argv) -{ -  UI *ui = UI(argv[0]); -  ui->busy_stop(ui); -} - -static void ui_bridge_mouse_on(UI *b) -{ -  UI_CALL(b, mouse_on, 1, b); -} -static void ui_bridge_mouse_on_event(void **argv) -{ -  UI *ui = UI(argv[0]); -  ui->mouse_on(ui); -} - -static void ui_bridge_mouse_off(UI *b) -{ -  UI_CALL(b, mouse_off, 1, b); -} -static void ui_bridge_mouse_off_event(void **argv) -{ -  UI *ui = UI(argv[0]); -  ui->mouse_off(ui); -} - -static void ui_bridge_mode_change(UI *b, int mode) -{ -  UI_CALL(b, mode_change, 2, b, INT2PTR(mode)); -} -static void ui_bridge_mode_change_event(void **argv) -{ -  UI *ui = UI(argv[0]); -  ui->mode_change(ui, PTR2INT(argv[1])); -} - -static void ui_bridge_set_scroll_region(UI *b, int top, int bot, int left, -                                        int right) -{ -  UI_CALL(b, set_scroll_region, 5, b, INT2PTR(top), INT2PTR(bot), -          INT2PTR(left), INT2PTR(right)); -} -static void ui_bridge_set_scroll_region_event(void **argv) -{ -  UI *ui = UI(argv[0]); -  ui->set_scroll_region(ui, PTR2INT(argv[1]), PTR2INT(argv[2]), -                        PTR2INT(argv[3]), PTR2INT(argv[4])); -} - -static void ui_bridge_scroll(UI *b, int count) -{ -  UI_CALL(b, scroll, 2, b, INT2PTR(count)); -} -static void ui_bridge_scroll_event(void **argv) -{ -  UI *ui = UI(argv[0]); -  ui->scroll(ui, PTR2INT(argv[1])); -} -  static void ui_bridge_highlight_set(UI *b, HlAttrs attrs)  {    HlAttrs *a = xmalloc(sizeof(HlAttrs));    *a = attrs; -  UI_CALL(b, highlight_set, 2, b, a); +  UI_BRIDGE_CALL(b, highlight_set, 2, b, a);  }  static void ui_bridge_highlight_set_event(void **argv)  { @@ -295,89 +146,13 @@ static void ui_bridge_highlight_set_event(void **argv)    xfree(argv[1]);  } -static void ui_bridge_put(UI *b, uint8_t *text, size_t size) -{ -  uint8_t *t = NULL; -  if (text) { -    t = xmalloc(sizeof(((UCell *)0)->data)); -    memcpy(t, text, size); -  } -  UI_CALL(b, put, 3, b, t, INT2PTR(size)); -} -static void ui_bridge_put_event(void **argv) -{ -  UI *ui = UI(argv[0]); -  ui->put(ui, (uint8_t *)argv[1], (size_t)(uintptr_t)argv[2]); -  xfree(argv[1]); -} - -static void ui_bridge_bell(UI *b) -{ -  UI_CALL(b, bell, 1, b); -} -static void ui_bridge_bell_event(void **argv) -{ -  UI *ui = UI(argv[0]); -  ui->bell(ui); -} - -static void ui_bridge_visual_bell(UI *b) -{ -  UI_CALL(b, visual_bell, 1, b); -} -static void ui_bridge_visual_bell_event(void **argv) -{ -  UI *ui = UI(argv[0]); -  ui->visual_bell(ui); -} - -static void ui_bridge_update_fg(UI *b, int fg) -{ -  UI_CALL(b, update_fg, 2, b, INT2PTR(fg)); -} -static void ui_bridge_update_fg_event(void **argv) -{ -  UI *ui = UI(argv[0]); -  ui->update_fg(ui, PTR2INT(argv[1])); -} - -static void ui_bridge_update_bg(UI *b, int bg) -{ -  UI_CALL(b, update_bg, 2, b, INT2PTR(bg)); -} -static void ui_bridge_update_bg_event(void **argv) -{ -  UI *ui = UI(argv[0]); -  ui->update_bg(ui, PTR2INT(argv[1])); -} - -static void ui_bridge_update_sp(UI *b, int sp) -{ -  UI_CALL(b, update_sp, 2, b, INT2PTR(sp)); -} -static void ui_bridge_update_sp_event(void **argv) -{ -  UI *ui = UI(argv[0]); -  ui->update_sp(ui, PTR2INT(argv[1])); -} - -static void ui_bridge_flush(UI *b) -{ -  UI_CALL(b, flush, 1, b); -} -static void ui_bridge_flush_event(void **argv) -{ -  UI *ui = UI(argv[0]); -  ui->flush(ui); -} -  static void ui_bridge_suspend(UI *b)  {    UIBridgeData *data = (UIBridgeData *)b;    uv_mutex_lock(&data->mutex); -  UI_CALL(b, suspend, 1, b); +  UI_BRIDGE_CALL(b, suspend, 1, b);    data->ready = false; -  // suspend the main thread until CONTINUE is called by the UI thread +  // Suspend the main thread until CONTINUE is called by the UI thread.    while (!data->ready) {      uv_cond_wait(&data->cond, &data->mutex);    } @@ -388,25 +163,3 @@ static void ui_bridge_suspend_event(void **argv)    UI *ui = UI(argv[0]);    ui->suspend(ui);  } - -static void ui_bridge_set_title(UI *b, char *title) -{ -  UI_CALL(b, set_title, 2, b, title ? xstrdup(title) : NULL); -} -static void ui_bridge_set_title_event(void **argv) -{ -  UI *ui = UI(argv[0]); -  ui->set_title(ui, argv[1]); -  xfree(argv[1]); -} - -static void ui_bridge_set_icon(UI *b, char *icon) -{ -  UI_CALL(b, set_icon, 2, b, icon ? xstrdup(icon) : NULL); -} -static void ui_bridge_set_icon_event(void **argv) -{ -  UI *ui = UI(argv[0]); -  ui->set_icon(ui, argv[1]); -  xfree(argv[1]); -} | 
