mirror of
				https://github.com/neovim/neovim.git
				synced 2025-11-04 01:34:25 +00:00 
			
		
		
		
	api: generate ui events
This commit is contained in:
		
							
								
								
									
										183
									
								
								scripts/gen_ui_events.lua
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										183
									
								
								scripts/gen_ui_events.lua
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,183 @@
 | 
			
		||||
lpeg = require('lpeg')
 | 
			
		||||
mpack = require('mpack')
 | 
			
		||||
 | 
			
		||||
-- TODO: reduce copying
 | 
			
		||||
-- lpeg grammar for building api metadata from a set of header files. It
 | 
			
		||||
-- ignores comments and preprocessor commands and parses a very small subset
 | 
			
		||||
-- of C prototypes with a limited set of types
 | 
			
		||||
P, R, S = lpeg.P, lpeg.R, lpeg.S
 | 
			
		||||
C, Ct, Cc, Cg = lpeg.C, lpeg.Ct, lpeg.Cc, lpeg.Cg
 | 
			
		||||
 | 
			
		||||
any = P(1) -- (consume one character)
 | 
			
		||||
letter = R('az', 'AZ') + S('_$')
 | 
			
		||||
num = R('09')
 | 
			
		||||
alpha = letter + num
 | 
			
		||||
nl = P('\r\n') + P('\n')
 | 
			
		||||
not_nl = any - nl
 | 
			
		||||
ws = S(' \t') + nl
 | 
			
		||||
fill = ws ^ 0
 | 
			
		||||
c_comment = P('//') * (not_nl ^ 0)
 | 
			
		||||
c_preproc = P('#') * (not_nl ^ 0)
 | 
			
		||||
typed_container =
 | 
			
		||||
  (P('ArrayOf(') + P('DictionaryOf(')) * ((any - P(')')) ^ 1) * P(')')
 | 
			
		||||
c_id = (
 | 
			
		||||
  typed_container +
 | 
			
		||||
  (letter * (alpha ^ 0))
 | 
			
		||||
)
 | 
			
		||||
c_void = P('void')
 | 
			
		||||
c_param_type = (
 | 
			
		||||
  ((P('Error') * fill * P('*') * fill) * Cc('error')) +
 | 
			
		||||
  (C(c_id) * (ws ^ 1))
 | 
			
		||||
  )
 | 
			
		||||
c_type = (C(c_void) * (ws ^ 1)) + c_param_type
 | 
			
		||||
c_param = Ct(c_param_type * C(c_id))
 | 
			
		||||
c_param_list = c_param * (fill * (P(',') * fill * c_param) ^ 0)
 | 
			
		||||
c_params = Ct(c_void + c_param_list)
 | 
			
		||||
c_proto = Ct(
 | 
			
		||||
  Cg(c_type, 'return_type') * Cg(c_id, 'name') *
 | 
			
		||||
  fill * P('(') * fill * Cg(c_params, 'parameters') * fill * P(')') *
 | 
			
		||||
  Cg(Cc(false), 'async') *
 | 
			
		||||
  (fill * Cg((P('FUNC_API_SINCE(') * C(num ^ 1)) * P(')'), 'since') ^ -1) *
 | 
			
		||||
  (fill * Cg((P('REMOTE_ONLY') * Cc(true)), 'remote_only') ^ -1) *
 | 
			
		||||
  (fill * Cg((P('REMOTE_IMPL') * Cc(true)), 'remote_impl') ^ -1) *
 | 
			
		||||
  (fill * Cg((P('BRIDGE_IMPL') * Cc(true)), 'bridge_impl') ^ -1) *
 | 
			
		||||
  fill * P(';')
 | 
			
		||||
  )
 | 
			
		||||
grammar = Ct((c_proto + c_comment + c_preproc + ws) ^ 1)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
-- we need at least 4 arguments since the last two are output files
 | 
			
		||||
assert(#arg == 6)
 | 
			
		||||
input = io.open(arg[2], 'rb')
 | 
			
		||||
proto_output = io.open(arg[3], 'wb')
 | 
			
		||||
call_output = io.open(arg[4], 'wb')
 | 
			
		||||
remote_output = io.open(arg[5], 'wb')
 | 
			
		||||
bridge_output = io.open(arg[6], 'wb')
 | 
			
		||||
 | 
			
		||||
functions = {}
 | 
			
		||||
 | 
			
		||||
local events = grammar:match(input:read('*all'))
 | 
			
		||||
 | 
			
		||||
function write_signature(output, ev, prefix, notype)
 | 
			
		||||
  output:write('('..prefix)
 | 
			
		||||
  if prefix == "" and #ev.parameters == 0 then
 | 
			
		||||
    output:write('void')
 | 
			
		||||
  end
 | 
			
		||||
  for j = 1, #ev.parameters do
 | 
			
		||||
    if j > 1 or prefix ~= '' then
 | 
			
		||||
      output:write(', ')
 | 
			
		||||
    end
 | 
			
		||||
    local param = ev.parameters[j]
 | 
			
		||||
    if not notype then
 | 
			
		||||
      output:write(param[1]..' ')
 | 
			
		||||
    end
 | 
			
		||||
    output:write(param[2])
 | 
			
		||||
  end
 | 
			
		||||
  output:write(')')
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function write_arglist(output, ev, need_copy)
 | 
			
		||||
  output:write('  Array args = ARRAY_DICT_INIT;\n')
 | 
			
		||||
  for j = 1, #ev.parameters do
 | 
			
		||||
    local param = ev.parameters[j]
 | 
			
		||||
    local kind = string.upper(param[1])
 | 
			
		||||
    local do_copy = need_copy and (kind == "ARRAY" or kind == "DICTIONARY" or kind == "STRING")
 | 
			
		||||
    output:write('  ADD(args, ')
 | 
			
		||||
    if do_copy then
 | 
			
		||||
      output:write('copy_object(')
 | 
			
		||||
    end
 | 
			
		||||
    output:write(kind..'_OBJ('..param[2]..')')
 | 
			
		||||
    if do_copy then
 | 
			
		||||
      output:write(')')
 | 
			
		||||
    end
 | 
			
		||||
    output:write(');\n')
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
for i = 1, #events do
 | 
			
		||||
  ev = events[i]
 | 
			
		||||
  assert(ev.return_type == 'void')
 | 
			
		||||
 | 
			
		||||
  if not ev.remote_only then
 | 
			
		||||
    proto_output:write('  void (*'..ev.name..')')
 | 
			
		||||
    write_signature(proto_output, ev, 'UI *ui')
 | 
			
		||||
    proto_output:write(';\n')
 | 
			
		||||
 | 
			
		||||
    if not ev.remote_impl then
 | 
			
		||||
      remote_output:write('static void remote_ui_'..ev.name)
 | 
			
		||||
      write_signature(remote_output, ev, 'UI *ui')
 | 
			
		||||
      remote_output:write('\n{\n')
 | 
			
		||||
      write_arglist(remote_output, ev, true)
 | 
			
		||||
      remote_output:write('  push_call(ui, "'..ev.name..'", args);\n')
 | 
			
		||||
      remote_output:write('}\n\n')
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    if not ev.bridge_impl then
 | 
			
		||||
 | 
			
		||||
      send, argv, recv, recv_argv, recv_cleanup = '', '', '', '', ''
 | 
			
		||||
      argc = 1
 | 
			
		||||
      for j = 1, #ev.parameters do
 | 
			
		||||
        local param = ev.parameters[j]
 | 
			
		||||
        copy = 'copy_'..param[2]
 | 
			
		||||
        if param[1] == 'String' then
 | 
			
		||||
          send = send..'  String copy_'..param[2]..' = copy_string('..param[2]..');\n'
 | 
			
		||||
          argv = argv..', '..copy..'.data, INT2PTR('..copy..'.size)'
 | 
			
		||||
          recv = (recv..'  String '..param[2]..
 | 
			
		||||
                          ' = (String){.data = argv['..argc..'],'..
 | 
			
		||||
                          '.size = (size_t)argv['..(argc+1)..']};\n')
 | 
			
		||||
          recv_argv = recv_argv..', '..param[2]
 | 
			
		||||
          recv_cleanup = recv_cleanup..'  api_free_string('..param[2]..');\n'
 | 
			
		||||
          argc = argc+2
 | 
			
		||||
        elseif param[1] == 'Array' then
 | 
			
		||||
          send = send..'  Array copy_'..param[2]..' = copy_array('..param[2]..');\n'
 | 
			
		||||
          argv = argv..', '..copy..'.items, INT2PTR('..copy..'.size)'
 | 
			
		||||
          recv = (recv..'  Array '..param[2]..
 | 
			
		||||
                          ' = (Array){.items = argv['..argc..'],'..
 | 
			
		||||
                          '.size = (size_t)argv['..(argc+1)..']};\n')
 | 
			
		||||
          recv_argv = recv_argv..', '..param[2]
 | 
			
		||||
          recv_cleanup = recv_cleanup..'  api_free_array('..param[2]..');\n'
 | 
			
		||||
          argc = argc+2
 | 
			
		||||
        elseif param[1] == 'Integer' or param[1] == 'Boolean' then
 | 
			
		||||
          argv = argv..', INT2PTR('..param[2]..')'
 | 
			
		||||
          recv_argv = recv_argv..', PTR2INT(argv['..argc..'])'
 | 
			
		||||
          argc = argc+1
 | 
			
		||||
        else
 | 
			
		||||
          assert(false)
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
      bridge_output:write('static void ui_bridge_'..ev.name..
 | 
			
		||||
                          '_event(void **argv)\n{\n')
 | 
			
		||||
      bridge_output:write('  UI *ui = UI(argv[0]);\n')
 | 
			
		||||
      bridge_output:write(recv)
 | 
			
		||||
      bridge_output:write('  ui->'..ev.name..'(ui'..recv_argv..');\n')
 | 
			
		||||
      bridge_output:write(recv_cleanup)
 | 
			
		||||
      bridge_output:write('}\n\n')
 | 
			
		||||
 | 
			
		||||
      bridge_output:write('static void ui_bridge_'..ev.name)
 | 
			
		||||
      write_signature(bridge_output, ev, 'UI *ui')
 | 
			
		||||
      bridge_output:write('\n{\n')
 | 
			
		||||
      bridge_output:write(send)
 | 
			
		||||
      bridge_output:write('  UI_CALL(ui, '..ev.name..', '..argc..', ui'..argv..');\n}\n')
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  call_output:write('void ui_call_'..ev.name)
 | 
			
		||||
  write_signature(call_output, ev, '')
 | 
			
		||||
  call_output:write('\n{\n')
 | 
			
		||||
  if ev.remote_only then
 | 
			
		||||
    write_arglist(call_output, ev, false)
 | 
			
		||||
    call_output:write('  ui_event("'..ev.name..'", args);\n')
 | 
			
		||||
  else
 | 
			
		||||
    call_output:write('  UI_CALL')
 | 
			
		||||
    write_signature(call_output, ev, ev.name, true)
 | 
			
		||||
    call_output:write(";\n")
 | 
			
		||||
  end
 | 
			
		||||
  call_output:write("}\n\n")
 | 
			
		||||
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
proto_output:close()
 | 
			
		||||
call_output:close()
 | 
			
		||||
remote_output:close()
 | 
			
		||||
@@ -87,6 +87,7 @@ for i = 6, #arg do
 | 
			
		||||
  headers[#headers + 1] = parts[#parts - 1]..'/'..parts[#parts]
 | 
			
		||||
 | 
			
		||||
  local input = io.open(full_path, 'rb')
 | 
			
		||||
 | 
			
		||||
  local tmp = grammar:match(input:read('*all'))
 | 
			
		||||
  for i = 1, #tmp do
 | 
			
		||||
    local fn = tmp[i]
 | 
			
		||||
 
 | 
			
		||||
@@ -13,6 +13,7 @@ endif()
 | 
			
		||||
set(TOUCHES_DIR ${PROJECT_BINARY_DIR}/touches)
 | 
			
		||||
set(GENERATED_DIR ${PROJECT_BINARY_DIR}/src/nvim/auto)
 | 
			
		||||
set(MSGPACK_GENERATOR ${PROJECT_SOURCE_DIR}/scripts/genmsgpack.lua)
 | 
			
		||||
set(API_UI_EVENTS_GENERATOR ${PROJECT_SOURCE_DIR}/scripts/gen_api_ui_events.lua)
 | 
			
		||||
set(API_METADATA ${PROJECT_BINARY_DIR}/api_metadata.mpack)
 | 
			
		||||
set(FUNCS_DATA ${PROJECT_BINARY_DIR}/funcs_data.mpack)
 | 
			
		||||
set(MSGPACK_LUA_C_BINDINGS ${GENERATED_DIR}/msgpack_lua_c_bindings.generated.c)
 | 
			
		||||
@@ -20,6 +21,10 @@ set(HEADER_GENERATOR ${PROJECT_SOURCE_DIR}/scripts/gendeclarations.lua)
 | 
			
		||||
set(GENERATED_INCLUDES_DIR ${PROJECT_BINARY_DIR}/include)
 | 
			
		||||
set(GENERATED_API_DISPATCH ${GENERATED_DIR}/api/private/dispatch_wrappers.generated.h)
 | 
			
		||||
set(GENERATED_FUNCS_METADATA ${GENERATED_DIR}/api/private/funcs_metadata.generated.h)
 | 
			
		||||
set(GENERATED_UI_EVENTS ${GENERATED_DIR}/ui_events.generated.h)
 | 
			
		||||
set(GENERATED_UI_EVENTS_CALL ${GENERATED_DIR}/ui_events_call.generated.h)
 | 
			
		||||
set(GENERATED_UI_EVENTS_REMOTE ${GENERATED_DIR}/ui_events_remote.generated.h)
 | 
			
		||||
set(GENERATED_UI_EVENTS_BRIDGE ${GENERATED_DIR}/ui_events_bridge.generated.h)
 | 
			
		||||
set(GENERATED_EX_CMDS_ENUM ${GENERATED_INCLUDES_DIR}/ex_cmds_enum.generated.h)
 | 
			
		||||
set(GENERATED_EX_CMDS_DEFS ${GENERATED_DIR}/ex_cmds_defs.generated.h)
 | 
			
		||||
set(GENERATED_FUNCS ${GENERATED_DIR}/funcs.generated.h)
 | 
			
		||||
@@ -49,6 +54,7 @@ set(LINT_SUPPRESSES_INSTALL_SCRIPT "${PROJECT_SOURCE_DIR}/cmake/InstallClintErro
 | 
			
		||||
 | 
			
		||||
file(GLOB UNICODE_FILES ${UNICODE_DIR}/*.txt)
 | 
			
		||||
file(GLOB API_HEADERS api/*.h)
 | 
			
		||||
list(REMOVE_ITEM API_HEADERS ${CMAKE_CURRENT_LIST_DIR}/api/ui_events.in.h)
 | 
			
		||||
file(GLOB MSGPACK_RPC_HEADERS msgpack_rpc/*.h)
 | 
			
		||||
 | 
			
		||||
include_directories(${GENERATED_DIR})
 | 
			
		||||
@@ -185,7 +191,11 @@ endfunction()
 | 
			
		||||
# These lists must be mutually exclusive.
 | 
			
		||||
foreach(sfile ${NVIM_SOURCES}
 | 
			
		||||
              "${CMAKE_CURRENT_LIST_DIR}/regexp_nfa.c"
 | 
			
		||||
              ${GENERATED_API_DISPATCH})
 | 
			
		||||
              ${GENERATED_API_DISPATCH}
 | 
			
		||||
              "${GENERATED_UI_EVENTS_CALL}"
 | 
			
		||||
              "${GENERATED_UI_EVENTS_REMOTE}"
 | 
			
		||||
              "${GENERATED_UI_EVENTS_BRIDGE}"
 | 
			
		||||
              )
 | 
			
		||||
  get_filename_component(full_d ${sfile} PATH)
 | 
			
		||||
  file(RELATIVE_PATH d "${CMAKE_CURRENT_LIST_DIR}" "${full_d}")
 | 
			
		||||
  if(${d} MATCHES "^[.][.]|auto/")
 | 
			
		||||
@@ -253,6 +263,21 @@ list(APPEND NVIM_GENERATED_SOURCES
 | 
			
		||||
  "${MSGPACK_LUA_C_BINDINGS}"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
add_custom_command(OUTPUT ${GENERATED_UI_EVENTS}
 | 
			
		||||
                          ${GENERATED_UI_EVENTS_CALL}
 | 
			
		||||
                          ${GENERATED_UI_EVENTS_REMOTE}
 | 
			
		||||
                          ${GENERATED_UI_EVENTS_BRIDGE}
 | 
			
		||||
  COMMAND ${LUA_PRG} ${API_UI_EVENTS_GENERATOR} ${CMAKE_CURRENT_LIST_DIR}
 | 
			
		||||
                     ${CMAKE_CURRENT_LIST_DIR}/api/ui_events.in.h
 | 
			
		||||
                     ${GENERATED_UI_EVENTS}
 | 
			
		||||
                     ${GENERATED_UI_EVENTS_CALL}
 | 
			
		||||
                     ${GENERATED_UI_EVENTS_REMOTE}
 | 
			
		||||
                     ${GENERATED_UI_EVENTS_BRIDGE}
 | 
			
		||||
  DEPENDS
 | 
			
		||||
    ${API_UI_EVENTS_GENERATOR}
 | 
			
		||||
    ${CMAKE_CURRENT_LIST_DIR}/api/ui_events.in.h
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
list(APPEND NVIM_GENERATED_FOR_HEADERS
 | 
			
		||||
  "${GENERATED_EX_CMDS_ENUM}"
 | 
			
		||||
  "${GENERATED_EVENTS_ENUM}"
 | 
			
		||||
@@ -518,7 +543,7 @@ set(NO_SINGLE_CHECK_HEADERS
 | 
			
		||||
foreach(hfile ${NVIM_HEADERS})
 | 
			
		||||
  get_test_target(test-includes "${hfile}" relative_path texe)
 | 
			
		||||
 | 
			
		||||
  if(NOT ${hfile} MATCHES "[.]c[.]h$")
 | 
			
		||||
  if(NOT ${hfile} MATCHES "[.](c|in)[.]h$")
 | 
			
		||||
    set(tsource "${GENERATED_DIR}/${relative_path}.test-include.c")
 | 
			
		||||
    write_file("${tsource}" "#include \"${hfile}\"\nint main(int argc, char **argv) { return 0; }")
 | 
			
		||||
    add_executable(
 | 
			
		||||
 
 | 
			
		||||
@@ -885,6 +885,24 @@ static void init_type_metadata(Dictionary *metadata)
 | 
			
		||||
  PUT(*metadata, "types", DICTIONARY_OBJ(types));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
String copy_string(String str)
 | 
			
		||||
{
 | 
			
		||||
  if (str.data != NULL) {
 | 
			
		||||
    return (String){ .data = xmemdupz(str.data, str.size), .size = str.size };
 | 
			
		||||
  } else {
 | 
			
		||||
    return (String)STRING_INIT;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Array copy_array(Array array)
 | 
			
		||||
{
 | 
			
		||||
  Array rv = ARRAY_DICT_INIT;
 | 
			
		||||
  for (size_t i = 0; i < array.size; i++) {
 | 
			
		||||
    ADD(rv, copy_object(array.items[i]));
 | 
			
		||||
  }
 | 
			
		||||
  return rv;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Creates a deep clone of an object
 | 
			
		||||
Object copy_object(Object obj)
 | 
			
		||||
{
 | 
			
		||||
@@ -896,15 +914,10 @@ Object copy_object(Object obj)
 | 
			
		||||
      return obj;
 | 
			
		||||
 | 
			
		||||
    case kObjectTypeString:
 | 
			
		||||
      return STRING_OBJ(cstr_to_string(obj.data.string.data));
 | 
			
		||||
      return STRING_OBJ(copy_string(obj.data.string));
 | 
			
		||||
 | 
			
		||||
    case kObjectTypeArray: {
 | 
			
		||||
      Array rv = ARRAY_DICT_INIT;
 | 
			
		||||
      for (size_t i = 0; i < obj.data.array.size; i++) {
 | 
			
		||||
        ADD(rv, copy_object(obj.data.array.items[i]));
 | 
			
		||||
      }
 | 
			
		||||
      return ARRAY_OBJ(rv);
 | 
			
		||||
    }
 | 
			
		||||
    case kObjectTypeArray:
 | 
			
		||||
      return ARRAY_OBJ(copy_array(obj.data.array));
 | 
			
		||||
 | 
			
		||||
    case kObjectTypeDictionary: {
 | 
			
		||||
      Dictionary rv = ARRAY_DICT_INIT;
 | 
			
		||||
 
 | 
			
		||||
@@ -19,6 +19,7 @@
 | 
			
		||||
 | 
			
		||||
#ifdef INCLUDE_GENERATED_DECLARATIONS
 | 
			
		||||
# include "api/ui.c.generated.h"
 | 
			
		||||
# include "ui_events_remote.generated.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
@@ -236,100 +237,6 @@ static void push_call(UI *ui, char *name, Array args)
 | 
			
		||||
  kv_A(data->buffer, kv_size(data->buffer) - 1).data.array = call;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void remote_ui_resize(UI *ui, int width, int height)
 | 
			
		||||
{
 | 
			
		||||
  Array args = ARRAY_DICT_INIT;
 | 
			
		||||
  ADD(args, INTEGER_OBJ(width));
 | 
			
		||||
  ADD(args, INTEGER_OBJ(height));
 | 
			
		||||
  push_call(ui, "resize", args);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void remote_ui_clear(UI *ui)
 | 
			
		||||
{
 | 
			
		||||
  Array args = ARRAY_DICT_INIT;
 | 
			
		||||
  push_call(ui, "clear", args);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void remote_ui_eol_clear(UI *ui)
 | 
			
		||||
{
 | 
			
		||||
  Array args = ARRAY_DICT_INIT;
 | 
			
		||||
  push_call(ui, "eol_clear", args);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void remote_ui_cursor_goto(UI *ui, int row, int col)
 | 
			
		||||
{
 | 
			
		||||
  Array args = ARRAY_DICT_INIT;
 | 
			
		||||
  ADD(args, INTEGER_OBJ(row));
 | 
			
		||||
  ADD(args, INTEGER_OBJ(col));
 | 
			
		||||
  push_call(ui, "cursor_goto", args);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void remote_ui_update_menu(UI *ui)
 | 
			
		||||
{
 | 
			
		||||
  Array args = ARRAY_DICT_INIT;
 | 
			
		||||
  push_call(ui, "update_menu", args);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void remote_ui_busy_start(UI *ui)
 | 
			
		||||
{
 | 
			
		||||
  Array args = ARRAY_DICT_INIT;
 | 
			
		||||
  push_call(ui, "busy_start", args);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void remote_ui_busy_stop(UI *ui)
 | 
			
		||||
{
 | 
			
		||||
  Array args = ARRAY_DICT_INIT;
 | 
			
		||||
  push_call(ui, "busy_stop", args);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void remote_ui_mouse_on(UI *ui)
 | 
			
		||||
{
 | 
			
		||||
  Array args = ARRAY_DICT_INIT;
 | 
			
		||||
  push_call(ui, "mouse_on", args);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void remote_ui_mouse_off(UI *ui)
 | 
			
		||||
{
 | 
			
		||||
  Array args = ARRAY_DICT_INIT;
 | 
			
		||||
  push_call(ui, "mouse_off", args);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void remote_ui_mode_change(UI *ui, int mode_idx)
 | 
			
		||||
{
 | 
			
		||||
  Array args = ARRAY_DICT_INIT;
 | 
			
		||||
 | 
			
		||||
  char *full_name = shape_table[mode_idx].full_name;
 | 
			
		||||
  ADD(args, STRING_OBJ(cstr_to_string(full_name)));
 | 
			
		||||
 | 
			
		||||
  ADD(args, INTEGER_OBJ(mode_idx));
 | 
			
		||||
  push_call(ui, "mode_change", args);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void remote_ui_set_scroll_region(UI *ui, int top, int bot, int left,
 | 
			
		||||
                                        int right)
 | 
			
		||||
{
 | 
			
		||||
  Array args = ARRAY_DICT_INIT;
 | 
			
		||||
  ADD(args, INTEGER_OBJ(top));
 | 
			
		||||
  ADD(args, INTEGER_OBJ(bot));
 | 
			
		||||
  ADD(args, INTEGER_OBJ(left));
 | 
			
		||||
  ADD(args, INTEGER_OBJ(right));
 | 
			
		||||
  push_call(ui, "set_scroll_region", args);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void remote_ui_scroll(UI *ui, int count)
 | 
			
		||||
{
 | 
			
		||||
  Array args = ARRAY_DICT_INIT;
 | 
			
		||||
  ADD(args, INTEGER_OBJ(count));
 | 
			
		||||
  push_call(ui, "scroll", args);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void remote_ui_mode_info_set(UI *ui, bool guicursor_enabled, Array data)
 | 
			
		||||
{
 | 
			
		||||
  Array args = ARRAY_DICT_INIT;
 | 
			
		||||
  ADD(args, BOOLEAN_OBJ(guicursor_enabled));
 | 
			
		||||
  ADD(args, copy_object(ARRAY_OBJ(data)));
 | 
			
		||||
  push_call(ui, "mode_info_set", args);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void remote_ui_highlight_set(UI *ui, HlAttrs attrs)
 | 
			
		||||
{
 | 
			
		||||
@@ -372,47 +279,6 @@ static void remote_ui_highlight_set(UI *ui, HlAttrs attrs)
 | 
			
		||||
  push_call(ui, "highlight_set", args);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void remote_ui_put(UI *ui, uint8_t *data, size_t size)
 | 
			
		||||
{
 | 
			
		||||
  Array args = ARRAY_DICT_INIT;
 | 
			
		||||
  String str = { .data = xmemdupz(data, size), .size = size };
 | 
			
		||||
  ADD(args, STRING_OBJ(str));
 | 
			
		||||
  push_call(ui, "put", args);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void remote_ui_bell(UI *ui)
 | 
			
		||||
{
 | 
			
		||||
  Array args = ARRAY_DICT_INIT;
 | 
			
		||||
  push_call(ui, "bell", args);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void remote_ui_visual_bell(UI *ui)
 | 
			
		||||
{
 | 
			
		||||
  Array args = ARRAY_DICT_INIT;
 | 
			
		||||
  push_call(ui, "visual_bell", args);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void remote_ui_update_fg(UI *ui, int fg)
 | 
			
		||||
{
 | 
			
		||||
  Array args = ARRAY_DICT_INIT;
 | 
			
		||||
  ADD(args, INTEGER_OBJ(fg));
 | 
			
		||||
  push_call(ui, "update_fg", args);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void remote_ui_update_bg(UI *ui, int bg)
 | 
			
		||||
{
 | 
			
		||||
  Array args = ARRAY_DICT_INIT;
 | 
			
		||||
  ADD(args, INTEGER_OBJ(bg));
 | 
			
		||||
  push_call(ui, "update_bg", args);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void remote_ui_update_sp(UI *ui, int sp)
 | 
			
		||||
{
 | 
			
		||||
  Array args = ARRAY_DICT_INIT;
 | 
			
		||||
  ADD(args, INTEGER_OBJ(sp));
 | 
			
		||||
  push_call(ui, "update_sp", args);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void remote_ui_flush(UI *ui)
 | 
			
		||||
{
 | 
			
		||||
  UIData *data = ui->data;
 | 
			
		||||
@@ -422,26 +288,6 @@ static void remote_ui_flush(UI *ui)
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void remote_ui_suspend(UI *ui)
 | 
			
		||||
{
 | 
			
		||||
  Array args = ARRAY_DICT_INIT;
 | 
			
		||||
  push_call(ui, "suspend", args);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void remote_ui_set_title(UI *ui, char *title)
 | 
			
		||||
{
 | 
			
		||||
  Array args = ARRAY_DICT_INIT;
 | 
			
		||||
  ADD(args, STRING_OBJ(cstr_to_string(title)));
 | 
			
		||||
  push_call(ui, "set_title", args);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void remote_ui_set_icon(UI *ui, char *icon)
 | 
			
		||||
{
 | 
			
		||||
  Array args = ARRAY_DICT_INIT;
 | 
			
		||||
  ADD(args, STRING_OBJ(cstr_to_string(icon)));
 | 
			
		||||
  push_call(ui, "set_icon", args);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void remote_ui_event(UI *ui, char *name, Array args, bool *args_consumed)
 | 
			
		||||
{
 | 
			
		||||
  Array my_args = ARRAY_DICT_INIT;
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										42
									
								
								src/nvim/api/ui_events.in.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								src/nvim/api/ui_events.in.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,42 @@
 | 
			
		||||
#ifndef NVIM_API_UI_EVENTS_IN_H
 | 
			
		||||
#define NVIM_API_UI_EVENTS_IN_H
 | 
			
		||||
 | 
			
		||||
// This file is not compiled, just parsed for definitons
 | 
			
		||||
#ifdef INCLUDE_GENERATED_DECLARATIONS
 | 
			
		||||
#error "don't include this file, include nvim/ui.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include "nvim/api/private/defs.h"
 | 
			
		||||
#include "nvim/func_attr.h"
 | 
			
		||||
#include "nvim/ui.h"
 | 
			
		||||
 | 
			
		||||
void resize(Integer rows, Integer columns);
 | 
			
		||||
void clear(void);
 | 
			
		||||
void eol_clear(void);
 | 
			
		||||
void cursor_goto(Integer row, Integer col);
 | 
			
		||||
void mode_info_set(Boolean enabled, Array cursor_styles);
 | 
			
		||||
void update_menu(void);
 | 
			
		||||
void busy_start(void);
 | 
			
		||||
void busy_stop(void);
 | 
			
		||||
void mouse_on(void);
 | 
			
		||||
void mouse_off(void);
 | 
			
		||||
void mode_change(String mode, Integer mode_idx);
 | 
			
		||||
void set_scroll_region(Integer top, Integer bot, Integer left, Integer right);
 | 
			
		||||
void scroll(Integer count);
 | 
			
		||||
void highlight_set(HlAttrs attrs) REMOTE_IMPL BRIDGE_IMPL;
 | 
			
		||||
void put(String str);
 | 
			
		||||
void bell(void);
 | 
			
		||||
void visual_bell(void);
 | 
			
		||||
void flush(void) REMOTE_IMPL;
 | 
			
		||||
void update_fg(Integer fg);
 | 
			
		||||
void update_bg(Integer bg);
 | 
			
		||||
void update_sp(Integer sp);
 | 
			
		||||
void suspend(void) BRIDGE_IMPL;
 | 
			
		||||
void set_title(String title);
 | 
			
		||||
void set_icon(String icon);
 | 
			
		||||
 | 
			
		||||
void popupmenu_show(Array items, Integer selected, Integer row, Integer col) REMOTE_ONLY;
 | 
			
		||||
void popupmenu_hide(void) REMOTE_ONLY;
 | 
			
		||||
void popupmenu_select(Integer selected) REMOTE_ONLY;
 | 
			
		||||
 | 
			
		||||
#endif  // NVIM_API_UI_EVENTS_IN_H
 | 
			
		||||
@@ -187,7 +187,7 @@ static void terminfo_stop(UI *ui)
 | 
			
		||||
{
 | 
			
		||||
  TUIData *data = ui->data;
 | 
			
		||||
  // Destroy output stuff
 | 
			
		||||
  tui_mode_change(ui, SHAPE_IDX_N);
 | 
			
		||||
  tui_mode_change(ui, (String)STRING_INIT, SHAPE_IDX_N);
 | 
			
		||||
  tui_mouse_off(ui);
 | 
			
		||||
  unibi_out(ui, unibi_exit_attribute_mode);
 | 
			
		||||
  // cursor should be set to normal before exiting alternate screen
 | 
			
		||||
@@ -417,14 +417,14 @@ static void clear_region(UI *ui, int top, int bot, int left, int right)
 | 
			
		||||
  unibi_goto(ui, grid->row, grid->col);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void tui_resize(UI *ui, int width, int height)
 | 
			
		||||
static void tui_resize(UI *ui, Integer width, Integer height)
 | 
			
		||||
{
 | 
			
		||||
  TUIData *data = ui->data;
 | 
			
		||||
  ugrid_resize(&data->grid, width, height);
 | 
			
		||||
  ugrid_resize(&data->grid, (int)width, (int)height);
 | 
			
		||||
 | 
			
		||||
  if (!got_winch) {  // Try to resize the terminal window.
 | 
			
		||||
    char r[16];  // enough for 9999x9999
 | 
			
		||||
    snprintf(r, sizeof(r), "\x1b[8;%d;%dt", height, width);
 | 
			
		||||
    snprintf(r, sizeof(r), "\x1b[8;%d;%dt", (int)height, (int)width);
 | 
			
		||||
    out(ui, r, strlen(r));
 | 
			
		||||
  } else {  // Already handled the SIGWINCH signal; avoid double-resize.
 | 
			
		||||
    got_winch = false;
 | 
			
		||||
@@ -447,11 +447,11 @@ static void tui_eol_clear(UI *ui)
 | 
			
		||||
  clear_region(ui, grid->row, grid->row, grid->col, grid->right);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void tui_cursor_goto(UI *ui, int row, int col)
 | 
			
		||||
static void tui_cursor_goto(UI *ui, Integer row, Integer col)
 | 
			
		||||
{
 | 
			
		||||
  TUIData *data = ui->data;
 | 
			
		||||
  ugrid_goto(&data->grid, row, col);
 | 
			
		||||
  unibi_goto(ui, row, col);
 | 
			
		||||
  ugrid_goto(&data->grid, (int)row, (int)col);
 | 
			
		||||
  unibi_goto(ui, (int)row, (int)col);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
CursorShape tui_cursor_decode_shape(const char *shape_str)
 | 
			
		||||
@@ -599,30 +599,31 @@ static void tui_set_mode(UI *ui, ModeShape mode)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// @param mode editor mode
 | 
			
		||||
static void tui_mode_change(UI *ui, int mode_idx)
 | 
			
		||||
static void tui_mode_change(UI *ui, String mode, Integer mode_idx)
 | 
			
		||||
{
 | 
			
		||||
  TUIData *data = ui->data;
 | 
			
		||||
  tui_set_mode(ui, (ModeShape)mode_idx);
 | 
			
		||||
  data->showing_mode = (ModeShape)mode_idx;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void tui_set_scroll_region(UI *ui, int top, int bot, int left,
 | 
			
		||||
                                  int right)
 | 
			
		||||
static void tui_set_scroll_region(UI *ui, Integer top, Integer bot,
 | 
			
		||||
                                  Integer left, Integer right)
 | 
			
		||||
{
 | 
			
		||||
  TUIData *data = ui->data;
 | 
			
		||||
  ugrid_set_scroll_region(&data->grid, top, bot, left, right);
 | 
			
		||||
  ugrid_set_scroll_region(&data->grid, (int)top, (int)bot,
 | 
			
		||||
                          (int)left, (int)right);
 | 
			
		||||
  data->can_use_terminal_scroll =
 | 
			
		||||
    left == 0 && right == ui->width - 1
 | 
			
		||||
    && ((top == 0 && bot == ui->height - 1)
 | 
			
		||||
        || unibi_get_str(data->ut, unibi_change_scroll_region));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void tui_scroll(UI *ui, int count)
 | 
			
		||||
static void tui_scroll(UI *ui, Integer count)
 | 
			
		||||
{
 | 
			
		||||
  TUIData *data = ui->data;
 | 
			
		||||
  UGrid *grid = &data->grid;
 | 
			
		||||
  int clear_top, clear_bot;
 | 
			
		||||
  ugrid_scroll(grid, count, &clear_top, &clear_bot);
 | 
			
		||||
  ugrid_scroll(grid, (int)count, &clear_top, &clear_bot);
 | 
			
		||||
 | 
			
		||||
  if (data->can_use_terminal_scroll) {
 | 
			
		||||
    // Change terminal scroll region and move cursor to the top
 | 
			
		||||
@@ -642,7 +643,7 @@ static void tui_scroll(UI *ui, int count)
 | 
			
		||||
      if (count == 1) {
 | 
			
		||||
        unibi_out(ui, unibi_delete_line);
 | 
			
		||||
      } else {
 | 
			
		||||
        data->params[0].i = count;
 | 
			
		||||
        data->params[0].i = (int)count;
 | 
			
		||||
        unibi_out(ui, unibi_parm_delete_line);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
@@ -652,7 +653,7 @@ static void tui_scroll(UI *ui, int count)
 | 
			
		||||
      if (count == -1) {
 | 
			
		||||
        unibi_out(ui, unibi_insert_line);
 | 
			
		||||
      } else {
 | 
			
		||||
        data->params[0].i = -count;
 | 
			
		||||
        data->params[0].i = -(int)count;
 | 
			
		||||
        unibi_out(ui, unibi_parm_insert_line);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
@@ -683,10 +684,10 @@ static void tui_highlight_set(UI *ui, HlAttrs attrs)
 | 
			
		||||
  ((TUIData *)ui->data)->grid.attrs = attrs;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void tui_put(UI *ui, uint8_t *text, size_t size)
 | 
			
		||||
static void tui_put(UI *ui, String text)
 | 
			
		||||
{
 | 
			
		||||
  TUIData *data = ui->data;
 | 
			
		||||
  print_cell(ui, ugrid_put(&data->grid, text, size));
 | 
			
		||||
  print_cell(ui, ugrid_put(&data->grid, (uint8_t *)text.data, text.size));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void tui_bell(UI *ui)
 | 
			
		||||
@@ -699,17 +700,17 @@ static void tui_visual_bell(UI *ui)
 | 
			
		||||
  unibi_out(ui, unibi_flash_screen);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void tui_update_fg(UI *ui, int fg)
 | 
			
		||||
static void tui_update_fg(UI *ui, Integer fg)
 | 
			
		||||
{
 | 
			
		||||
  ((TUIData *)ui->data)->grid.fg = fg;
 | 
			
		||||
  ((TUIData *)ui->data)->grid.fg = (int)fg;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void tui_update_bg(UI *ui, int bg)
 | 
			
		||||
static void tui_update_bg(UI *ui, Integer bg)
 | 
			
		||||
{
 | 
			
		||||
  ((TUIData *)ui->data)->grid.bg = bg;
 | 
			
		||||
  ((TUIData *)ui->data)->grid.bg = (int)bg;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void tui_update_sp(UI *ui, int sp)
 | 
			
		||||
static void tui_update_sp(UI *ui, Integer sp)
 | 
			
		||||
{
 | 
			
		||||
  // Do nothing; 'special' color is for GUI only
 | 
			
		||||
}
 | 
			
		||||
@@ -784,19 +785,19 @@ static void tui_suspend(UI *ui)
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void tui_set_title(UI *ui, char *title)
 | 
			
		||||
static void tui_set_title(UI *ui, String title)
 | 
			
		||||
{
 | 
			
		||||
  TUIData *data = ui->data;
 | 
			
		||||
  if (!(title && unibi_get_str(data->ut, unibi_to_status_line)
 | 
			
		||||
  if (!(title.data && unibi_get_str(data->ut, unibi_to_status_line)
 | 
			
		||||
        && unibi_get_str(data->ut, unibi_from_status_line))) {
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
  unibi_out(ui, unibi_to_status_line);
 | 
			
		||||
  out(ui, title, strlen(title));
 | 
			
		||||
  out(ui, title.data, title.size);
 | 
			
		||||
  unibi_out(ui, unibi_from_status_line);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void tui_set_icon(UI *ui, char *icon)
 | 
			
		||||
static void tui_set_icon(UI *ui, String icon)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -89,6 +89,10 @@ static int old_mode_idx = -1;
 | 
			
		||||
#define UI_CALL_MORE(method, ...) if (ui->method) ui->method(ui, __VA_ARGS__)
 | 
			
		||||
#define UI_CALL_ZERO(method) if (ui->method) ui->method(ui)
 | 
			
		||||
 | 
			
		||||
#ifdef INCLUDE_GENERATED_DECLARATIONS
 | 
			
		||||
# include "ui_events_call.generated.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
void ui_builtin_start(void)
 | 
			
		||||
{
 | 
			
		||||
#ifdef FEAT_TUI
 | 
			
		||||
@@ -136,13 +140,13 @@ void ui_suspend(void)
 | 
			
		||||
 | 
			
		||||
void ui_set_title(char *title)
 | 
			
		||||
{
 | 
			
		||||
  UI_CALL(set_title, title);
 | 
			
		||||
  ui_call_set_title(cstr_as_string(title));
 | 
			
		||||
  UI_CALL(flush);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ui_set_icon(char *icon)
 | 
			
		||||
{
 | 
			
		||||
  UI_CALL(set_icon, icon);
 | 
			
		||||
  ui_call_set_icon(cstr_as_string(icon));
 | 
			
		||||
  UI_CALL(flush);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -390,7 +394,7 @@ void ui_mode_info_set(void)
 | 
			
		||||
{
 | 
			
		||||
  Array style = mode_style_array();
 | 
			
		||||
  bool enabled = (*p_guicursor != NUL);
 | 
			
		||||
  UI_CALL(mode_info_set, enabled, style);
 | 
			
		||||
  ui_call_mode_info_set(enabled, style);
 | 
			
		||||
  api_free_array(style);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -420,11 +424,11 @@ static void send_output(uint8_t **ptr)
 | 
			
		||||
 | 
			
		||||
  while (*p >= 0x20) {
 | 
			
		||||
    size_t clen = (size_t)mb_ptr2len(p);
 | 
			
		||||
    UI_CALL(put, p, (size_t)clen);
 | 
			
		||||
    ui_call_put((String){.data = (char *)p, .size = clen});
 | 
			
		||||
    col++;
 | 
			
		||||
    if (mb_ptr2cells(p) > 1) {
 | 
			
		||||
      // double cell character, blank the next cell
 | 
			
		||||
      UI_CALL(put, NULL, 0);
 | 
			
		||||
      ui_call_put((String)STRING_INIT);
 | 
			
		||||
      col++;
 | 
			
		||||
    }
 | 
			
		||||
    if (utf_ambiguous_width(utf_ptr2char(p))) {
 | 
			
		||||
@@ -560,7 +564,8 @@ void ui_cursor_shape(void)
 | 
			
		||||
 | 
			
		||||
  if (old_mode_idx != mode_idx) {
 | 
			
		||||
    old_mode_idx = mode_idx;
 | 
			
		||||
    UI_CALL(mode_change, mode_idx);
 | 
			
		||||
    char *full_name = shape_table[mode_idx].full_name;
 | 
			
		||||
    ui_call_mode_change(cstr_as_string(full_name), mode_idx);
 | 
			
		||||
  }
 | 
			
		||||
  conceal_check_cursur_line();
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -28,35 +28,17 @@ struct ui_t {
 | 
			
		||||
  bool ui_ext[UI_WIDGETS];  ///< Externalized widgets
 | 
			
		||||
  int width, height;
 | 
			
		||||
  void *data;
 | 
			
		||||
  void (*resize)(UI *ui, int rows, int columns);
 | 
			
		||||
  void (*clear)(UI *ui);
 | 
			
		||||
  void (*eol_clear)(UI *ui);
 | 
			
		||||
  void (*cursor_goto)(UI *ui, int row, int col);
 | 
			
		||||
  void (*mode_info_set)(UI *ui, bool enabled, Array cursor_styles);
 | 
			
		||||
  void (*update_menu)(UI *ui);
 | 
			
		||||
  void (*busy_start)(UI *ui);
 | 
			
		||||
  void (*busy_stop)(UI *ui);
 | 
			
		||||
  void (*mouse_on)(UI *ui);
 | 
			
		||||
  void (*mouse_off)(UI *ui);
 | 
			
		||||
  void (*mode_change)(UI *ui, int mode_idx);
 | 
			
		||||
  void (*set_scroll_region)(UI *ui, int top, int bot, int left, int right);
 | 
			
		||||
  void (*scroll)(UI *ui, int count);
 | 
			
		||||
  void (*highlight_set)(UI *ui, HlAttrs attrs);
 | 
			
		||||
  void (*put)(UI *ui, uint8_t *str, size_t len);
 | 
			
		||||
  void (*bell)(UI *ui);
 | 
			
		||||
  void (*visual_bell)(UI *ui);
 | 
			
		||||
  void (*flush)(UI *ui);
 | 
			
		||||
  void (*update_fg)(UI *ui, int fg);
 | 
			
		||||
  void (*update_bg)(UI *ui, int bg);
 | 
			
		||||
  void (*update_sp)(UI *ui, int sp);
 | 
			
		||||
  void (*suspend)(UI *ui);
 | 
			
		||||
  void (*set_title)(UI *ui, char *title);
 | 
			
		||||
  void (*set_icon)(UI *ui, char *icon);
 | 
			
		||||
 | 
			
		||||
#ifdef INCLUDE_GENERATED_DECLARATIONS
 | 
			
		||||
# include "ui_events.generated.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
  void (*event)(UI *ui, char *name, Array args, bool *args_consumed);
 | 
			
		||||
  void (*stop)(UI *ui);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#ifdef INCLUDE_GENERATED_DECLARATIONS
 | 
			
		||||
# include "ui.h.generated.h"
 | 
			
		||||
# include "ui_events_call.h.generated.h"
 | 
			
		||||
#endif
 | 
			
		||||
#endif  // NVIM_UI_H
 | 
			
		||||
 
 | 
			
		||||
@@ -49,8 +49,12 @@ static argv_callback uilog_event = NULL;
 | 
			
		||||
      event_create(ui_bridge_##name##_event, argc, __VA_ARGS__), UI(ui))
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define INT2PTR(i) ((void *)(uintptr_t)i)
 | 
			
		||||
#define PTR2INT(p) ((int)(uintptr_t)p)
 | 
			
		||||
#define INT2PTR(i) ((void *)(intptr_t)i)
 | 
			
		||||
#define PTR2INT(p) ((Integer)(intptr_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)
 | 
			
		||||
{
 | 
			
		||||
@@ -146,148 +150,6 @@ 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_mode_info_set(UI *b, bool enabled, Array modes)
 | 
			
		||||
{
 | 
			
		||||
  bool *enabledp = xmalloc(sizeof(*enabledp));
 | 
			
		||||
  Object *modesp = xmalloc(sizeof(*modesp));
 | 
			
		||||
  *enabledp = enabled;
 | 
			
		||||
  *modesp = copy_object(ARRAY_OBJ(modes));
 | 
			
		||||
  UI_CALL(b, mode_info_set, 3, b, enabledp, modesp);
 | 
			
		||||
}
 | 
			
		||||
static void ui_bridge_mode_info_set_event(void **argv)
 | 
			
		||||
{
 | 
			
		||||
  UI *ui = UI(argv[0]);
 | 
			
		||||
  bool *enabled = argv[1];
 | 
			
		||||
  Object *modes = argv[2];
 | 
			
		||||
  ui->mode_info_set(ui, *enabled, modes->data.array);
 | 
			
		||||
  xfree(enabled);
 | 
			
		||||
  api_free_object(*modes);
 | 
			
		||||
  xfree(modes);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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_idx)
 | 
			
		||||
{
 | 
			
		||||
  UI_CALL(b, mode_change, 2, b, INT2PTR(mode_idx));
 | 
			
		||||
}
 | 
			
		||||
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));
 | 
			
		||||
@@ -301,82 +163,6 @@ 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;
 | 
			
		||||
@@ -394,25 +180,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]);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user