diff --git a/boards/posix/common/sdl/CMakeLists.txt b/boards/posix/common/sdl/CMakeLists.txt index b2d4d815443e32..a790845afd856a 100644 --- a/boards/posix/common/sdl/CMakeLists.txt +++ b/boards/posix/common/sdl/CMakeLists.txt @@ -6,11 +6,19 @@ zephyr_library_compile_definitions(NO_POSIX_CHEATS) find_package(PkgConfig REQUIRED) pkg_search_module(SDL2 REQUIRED sdl2) -zephyr_include_directories(${SDL2_INCLUDE_DIRS}) + if (CONFIG_NATIVE_APPLICATION) zephyr_link_libraries(${SDL2_LIBRARIES}) + zephyr_include_directories(${SDL2_INCLUDE_DIRS}) + zephyr_compile_options(${SDL2_CFLAGS_OTHER}) else() target_link_options(native_simulator INTERFACE "-l${SDL2_LIBRARIES}") + target_compile_options(native_simulator INTERFACE "-I${SDL2_INCLUDE_DIRS}" ${SDL2_CFLAGS_OTHER}) endif() -zephyr_compile_options(${SDL2_CFLAGS_OTHER}) + zephyr_library_sources(sdl_events.c) +if (CONFIG_NATIVE_APPLICATION) + zephyr_library_sources(sdl_events_bottom.c) +else() + target_sources(native_simulator INTERFACE sdl_events_bottom.c) +endif() diff --git a/boards/posix/common/sdl/sdl_events.c b/boards/posix/common/sdl/sdl_events.c index e2cb2042d7bd5f..6c6d16f681ea46 100644 --- a/boards/posix/common/sdl/sdl_events.c +++ b/boards/posix/common/sdl/sdl_events.c @@ -8,53 +8,19 @@ #include "soc.h" #include #include - -#include - -static void sdl_handle_window_event(const SDL_Event *event) -{ - SDL_Window *window; - SDL_Renderer *renderer; - - switch (event->window.event) { - case SDL_WINDOWEVENT_EXPOSED: - - window = SDL_GetWindowFromID(event->window.windowID); - if (window == NULL) { - return; - } - - renderer = SDL_GetRenderer(window); - if (renderer == NULL) { - return; - } - SDL_RenderPresent(renderer); - break; - default: - break; - } -} +#include "sdl_events_bottom.h" static void sdl_handle_events(void *p1, void *p2, void *p3) { - SDL_Event event; - ARG_UNUSED(p1); ARG_UNUSED(p2); ARG_UNUSED(p3); for (;;) { - while (SDL_PollEvent(&event)) { - switch (event.type) { - case SDL_WINDOWEVENT: - sdl_handle_window_event(&event); - break; - case SDL_QUIT: - posix_exit(0); - break; - default: - break; - } + int rc = sdl_handle_pending_events(); + + if (rc != 0) { + posix_exit(0); } k_msleep(CONFIG_SDL_THREAD_INTERVAL); @@ -63,15 +29,14 @@ static void sdl_handle_events(void *p1, void *p2, void *p3) static void sdl_init(void) { - if (SDL_Init(SDL_INIT_VIDEO) != 0) { - posix_print_error_and_exit("Error on SDL_Init (%s)\n", - SDL_GetError()); + if (sdl_init_video() != 0) { + posix_print_error_and_exit("Error on SDL_Init (%s)\n", sdl_get_error()); } } static void sdl_cleanup(void) { - SDL_Quit(); + sdl_quit(); } NATIVE_TASK(sdl_init, PRE_BOOT_2, 1); diff --git a/boards/posix/common/sdl/sdl_events_bottom.c b/boards/posix/common/sdl/sdl_events_bottom.c new file mode 100644 index 00000000000000..873fa4be446fa8 --- /dev/null +++ b/boards/posix/common/sdl/sdl_events_bottom.c @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2018 Jan Van Winkel + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + * + * "Bottom" of the SDL event handler for the POSIX architecture. + * When built with the native_simulator this will be built in the runner context, + * that is, with the host C library, and with the host include paths. + * + * Therefore it cannot include Zephyr headers + */ + +#include + +static void sdl_handle_window_event(const SDL_Event *event) +{ + SDL_Window *window; + SDL_Renderer *renderer; + + switch (event->window.event) { + case SDL_WINDOWEVENT_EXPOSED: + + window = SDL_GetWindowFromID(event->window.windowID); + if (window == NULL) { + return; + } + + renderer = SDL_GetRenderer(window); + if (renderer == NULL) { + return; + } + SDL_RenderPresent(renderer); + break; + default: + break; + } +} + +/* + * Handle all pending display events + * Return 1 if the window was closed, 0 otherwise. + */ +int sdl_handle_pending_events(void) +{ + SDL_Event event; + + while (SDL_PollEvent(&event)) { + switch (event.type) { + case SDL_WINDOWEVENT: + sdl_handle_window_event(&event); + break; + case SDL_QUIT: + return 1; + default: + break; + } + } + return 0; +} + +/* + * Initialize the SDL library + * + * Returns 0 on success, something else on failure. + */ +int sdl_init_video(void) +{ + return SDL_Init(SDL_INIT_VIDEO); +} + +/* + * Trampoline to SDL_GetError + */ +const char *sdl_get_error(void) +{ + return SDL_GetError(); +} + +/* + * Trampoline to SDL_Quit() + */ +void sdl_quit(void) +{ + SDL_Quit(); +} diff --git a/boards/posix/common/sdl/sdl_events_bottom.h b/boards/posix/common/sdl/sdl_events_bottom.h new file mode 100644 index 00000000000000..ab622301797448 --- /dev/null +++ b/boards/posix/common/sdl/sdl_events_bottom.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef BOARDS_POSIX_COMMON_SDL_SDL_EVENTS_BOTTOM_H +#define BOARDS_POSIX_COMMON_SDL_SDL_EVENTS_BOTTOM_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Note: None of these functions are public interfaces. But internal to the SDL event handling */ + +int sdl_handle_pending_events(void); +int sdl_init_video(void); +void sdl_quit(void); +const char *sdl_get_error(void); + +#ifdef __cplusplus +} +#endif + +#endif /* BOARDS_POSIX_COMMON_SDL_SDL_EVENTS_BOTTOM_H */ diff --git a/boards/posix/native_sim/doc/index.rst b/boards/posix/native_sim/doc/index.rst index 42cef26e40cd27..2c4d53111c41c4 100644 --- a/boards/posix/native_sim/doc/index.rst +++ b/boards/posix/native_sim/doc/index.rst @@ -108,16 +108,16 @@ host libC (:kconfig:option:`CONFIG_EXTERNAL_LIBC`). bluetooth, userchan, :kconfig:option:`CONFIG_BT_USERCHAN`, host libC can, can native posix, :kconfig:option:`CONFIG_CAN_NATIVE_POSIX_LINUX`, host libC console backend, POSIX arch console, :kconfig:option:`CONFIG_POSIX_ARCH_CONSOLE`, all - display, display SDL, :kconfig:option:`CONFIG_SDL_DISPLAY`, host libC + display, display SDL, :kconfig:option:`CONFIG_SDL_DISPLAY`, all entropy, native posix entropy, :kconfig:option:`CONFIG_FAKE_ENTROPY_NATIVE_POSIX`, host libC eprom, eprom emulator, :kconfig:option:`CONFIG_EEPROM_EMULATOR`, host libC ethernet, eth native_posix, :kconfig:option:`CONFIG_ETH_NATIVE_POSIX`, host libC flash, flash simulator, :kconfig:option:`CONFIG_FLASH_SIMULATOR`, host libC flash, host based flash access, :kconfig:option:`CONFIG_FUSE_FS_ACCESS`, host libC gpio, GPIO emulator, :kconfig:option:`CONFIG_GPIO_EMUL`, all - gpio, SDL GPIO emulator, :kconfig:option:`CONFIG_GPIO_EMUL_SDL`, host libC + gpio, SDL GPIO emulator, :kconfig:option:`CONFIG_GPIO_EMUL_SDL`, all i2c, I2C emulator, :kconfig:option:`CONFIG_I2C_EMUL`, all - input, input SDL touch, :kconfig:option:`CONFIG_INPUT_SDL_TOUCH`, host libC + input, input SDL touch, :kconfig:option:`CONFIG_INPUT_SDL_TOUCH`, all log backend, native backend, :kconfig:option:`CONFIG_LOG_BACKEND_NATIVE_POSIX`, all rtc, RTC emul, :kconfig:option:`CONFIG_RTC_EMUL`, all serial, uart native posix/PTTY, :kconfig:option:`CONFIG_UART_NATIVE_POSIX`, host libC diff --git a/drivers/display/CMakeLists.txt b/drivers/display/CMakeLists.txt index 4e7bcd024da695..fd655f1894f805 100644 --- a/drivers/display/CMakeLists.txt +++ b/drivers/display/CMakeLists.txt @@ -15,7 +15,6 @@ zephyr_library_sources_ifdef(CONFIG_ILI9488 display_ili9488.c) zephyr_library_sources_ifdef(CONFIG_LS0XX ls0xx.c) zephyr_library_sources_ifdef(CONFIG_MAX7219 display_max7219.c) zephyr_library_sources_ifdef(CONFIG_OTM8009A display_otm8009a.c) -zephyr_library_sources_ifdef(CONFIG_SDL_DISPLAY display_sdl.c) zephyr_library_sources_ifdef(CONFIG_SSD1306 ssd1306.c) zephyr_library_sources_ifdef(CONFIG_SSD16XX ssd16xx.c) zephyr_library_sources_ifdef(CONFIG_ST7789V display_st7789v.c) @@ -27,3 +26,12 @@ zephyr_library_sources_ifdef(CONFIG_MICROBIT_DISPLAY mb_display.c mb_font.c ) + +if (CONFIG_SDL_DISPLAY) + zephyr_library_sources(display_sdl.c) + if (CONFIG_NATIVE_APPLICATION) + zephyr_library_sources(display_sdl_bottom.c) + else() + target_sources(native_simulator INTERFACE display_sdl_bottom.c) + endif() +endif() diff --git a/drivers/display/Kconfig.sdl b/drivers/display/Kconfig.sdl index d2d11f4688e918..a06b143f31ed4d 100644 --- a/drivers/display/Kconfig.sdl +++ b/drivers/display/Kconfig.sdl @@ -7,7 +7,6 @@ menuconfig SDL_DISPLAY bool "SDL based emulated display" default y depends on DT_HAS_ZEPHYR_SDL_DC_ENABLED - depends on EXTERNAL_LIBC select HAS_SDL help Enable SDL based emulated display compliant with display driver API. diff --git a/drivers/display/display_sdl.c b/drivers/display/display_sdl.c index f70613a34c3560..f7ada84fbea752 100644 --- a/drivers/display/display_sdl.c +++ b/drivers/display/display_sdl.c @@ -9,10 +9,10 @@ #include -#include #include #include #include +#include "display_sdl_bottom.h" #define LOG_LEVEL CONFIG_DISPLAY_LOG_LEVEL #include @@ -24,9 +24,9 @@ struct sdl_display_config { }; struct sdl_display_data { - SDL_Window *window; - SDL_Renderer *renderer; - SDL_Texture *texture; + void *window; + void *renderer; + void *texture; bool display_on; enum display_pixel_format current_pixel_format; uint8_t *buf; @@ -54,36 +54,15 @@ static int sdl_display_init(const struct device *dev) #endif /* SDL_DISPLAY_DEFAULT_PIXEL_FORMAT */ ; - disp_data->window = - SDL_CreateWindow("Zephyr Display", SDL_WINDOWPOS_UNDEFINED, - SDL_WINDOWPOS_UNDEFINED, config->width, - config->height, SDL_WINDOW_SHOWN); - if (disp_data->window == NULL) { - LOG_ERR("Failed to create SDL window: %s", SDL_GetError()); - return -EIO; - } + int rc = sdl_display_init_bottom(config->height, config->width, &disp_data->window, + &disp_data->renderer, &disp_data->texture); - disp_data->renderer = - SDL_CreateRenderer(disp_data->window, -1, SDL_RENDERER_ACCELERATED); - if (disp_data->renderer == NULL) { - LOG_ERR("Failed to create SDL renderer: %s", - SDL_GetError()); - return -EIO; - } - - disp_data->texture = SDL_CreateTexture( - disp_data->renderer, SDL_PIXELFORMAT_ARGB8888, - SDL_TEXTUREACCESS_STATIC, config->width, - config->height); - if (disp_data->texture == NULL) { - LOG_ERR("Failed to create SDL texture: %s", SDL_GetError()); + if (rc != 0) { + LOG_ERR("Failed to create SDL display"); return -EIO; } disp_data->display_on = false; - SDL_SetRenderDrawColor(disp_data->renderer, 0, 0, 0, 0xFF); - SDL_RenderClear(disp_data->renderer); - SDL_RenderPresent(disp_data->renderer); return 0; } @@ -222,7 +201,6 @@ static int sdl_display_write(const struct device *dev, const uint16_t x, { const struct sdl_display_config *config = dev->config; struct sdl_display_data *disp_data = dev->data; - SDL_Rect rect; LOG_DBG("Writing %dx%d (w,h) bitmap @ %dx%d (x,y)", desc->width, desc->height, x, y); @@ -257,20 +235,9 @@ static int sdl_display_write(const struct device *dev, const uint16_t x, sdl_display_write_bgr565(disp_data->buf, desc, buf); } - rect.x = x; - rect.y = y; - rect.w = desc->width; - rect.h = desc->height; - - SDL_UpdateTexture(disp_data->texture, &rect, disp_data->buf, - 4 * rect.w); - - if (disp_data->display_on) { - SDL_RenderClear(disp_data->renderer); - SDL_RenderCopy(disp_data->renderer, disp_data->texture, NULL, - NULL); - SDL_RenderPresent(disp_data->renderer); - } + sdl_display_write_bottom(desc->height, desc->width, x, y, + disp_data->renderer, disp_data->texture, + disp_data->buf, disp_data->display_on); return 0; } @@ -281,12 +248,6 @@ static int sdl_display_read(const struct device *dev, const uint16_t x, void *buf) { struct sdl_display_data *disp_data = dev->data; - SDL_Rect rect; - - rect.x = x; - rect.y = y; - rect.w = desc->width; - rect.h = desc->height; LOG_DBG("Reading %dx%d (w,h) bitmap @ %dx%d (x,y)", desc->width, desc->height, x, y); @@ -295,8 +256,8 @@ static int sdl_display_read(const struct device *dev, const uint16_t x, __ASSERT((desc->pitch * 3U * desc->height) <= desc->buf_size, "Input buffer to small"); - return SDL_RenderReadPixels(disp_data->renderer, &rect, 0, buf, - desc->pitch * 4U); + return sdl_display_read_bottom(desc->height, desc->width, x, y, + disp_data->renderer, buf, desc->pitch); } static void *sdl_display_get_framebuffer(const struct device *dev) @@ -312,9 +273,7 @@ static int sdl_display_blanking_off(const struct device *dev) disp_data->display_on = true; - SDL_RenderClear(disp_data->renderer); - SDL_RenderCopy(disp_data->renderer, disp_data->texture, NULL, NULL); - SDL_RenderPresent(disp_data->renderer); + sdl_display_blanking_off_bottom(disp_data->renderer, disp_data->texture); return 0; } @@ -327,8 +286,7 @@ static int sdl_display_blanking_on(const struct device *dev) disp_data->display_on = false; - SDL_RenderClear(disp_data->renderer); - SDL_RenderPresent(disp_data->renderer); + sdl_display_blanking_on_bottom(disp_data->renderer); return 0; } @@ -386,20 +344,7 @@ static int sdl_display_set_pixel_format(const struct device *dev, static void sdl_display_cleanup(struct sdl_display_data *disp_data) { - if (disp_data->texture != NULL) { - SDL_DestroyTexture(disp_data->texture); - disp_data->texture = NULL; - } - - if (disp_data->renderer != NULL) { - SDL_DestroyRenderer(disp_data->renderer); - disp_data->renderer = NULL; - } - - if (disp_data->window != NULL) { - SDL_DestroyWindow(disp_data->window); - disp_data->window = NULL; - } + sdl_display_cleanup_bottom(&disp_data->window, &disp_data->renderer, &disp_data->texture); } static const struct display_driver_api sdl_display_api = { diff --git a/drivers/display/display_sdl_bottom.c b/drivers/display/display_sdl_bottom.c new file mode 100644 index 00000000000000..a7ad1929f4ea96 --- /dev/null +++ b/drivers/display/display_sdl_bottom.c @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2018 Jan Van Winkel + * Copyright (c) 2023 Nordic Semiconductor + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include "nsi_tracing.h" + +int sdl_display_init_bottom(uint16_t height, uint16_t width, + void **window, void **renderer, void **texture) +{ + *window = SDL_CreateWindow("Zephyr Display", SDL_WINDOWPOS_UNDEFINED, + SDL_WINDOWPOS_UNDEFINED, width, + height, SDL_WINDOW_SHOWN); + if (*window == NULL) { + nsi_print_warning("Failed to create SDL window: %s", SDL_GetError()); + return -1; + } + + *renderer = SDL_CreateRenderer(*window, -1, SDL_RENDERER_ACCELERATED); + if (*renderer == NULL) { + nsi_print_warning("Failed to create SDL renderer: %s", + SDL_GetError()); + return -1; + } + + *texture = SDL_CreateTexture(*renderer, SDL_PIXELFORMAT_ARGB8888, + SDL_TEXTUREACCESS_STATIC, width, height); + if (*texture == NULL) { + nsi_print_warning("Failed to create SDL texture: %s", SDL_GetError()); + return -1; + } + + SDL_SetRenderDrawColor(*renderer, 0, 0, 0, 0xFF); + SDL_RenderClear(*renderer); + SDL_RenderPresent(*renderer); + + return 0; +} + +void sdl_display_write_bottom(const uint16_t height, const uint16_t width, + const uint16_t x, const uint16_t y, + void *renderer, void *texture, + uint8_t *buf, bool display_on) +{ + SDL_Rect rect; + + rect.x = x; + rect.y = y; + rect.w = width; + rect.h = height; + + SDL_UpdateTexture(texture, &rect, buf, 4 * rect.w); + + if (display_on) { + SDL_RenderClear(renderer); + SDL_RenderCopy(renderer, texture, NULL, NULL); + SDL_RenderPresent(renderer); + } +} + +int sdl_display_read_bottom(const uint16_t height, const uint16_t width, + const uint16_t x, const uint16_t y, + void *renderer, void *buf, uint16_t pitch) +{ + SDL_Rect rect; + + rect.x = x; + rect.y = y; + rect.w = width; + rect.h = height; + + return SDL_RenderReadPixels(renderer, &rect, 0, buf, pitch * 4U); +} + +void sdl_display_blanking_off_bottom(void *renderer, void *texture) +{ + SDL_RenderClear(renderer); + SDL_RenderCopy(renderer, texture, NULL, NULL); + SDL_RenderPresent(renderer); +} + +void sdl_display_blanking_on_bottom(void *renderer) +{ + SDL_RenderClear(renderer); + SDL_RenderPresent(renderer); +} + +void sdl_display_cleanup_bottom(void **window, void **renderer, void **texture) +{ + if (*texture != NULL) { + SDL_DestroyTexture(*texture); + *texture = NULL; + } + + if (*renderer != NULL) { + SDL_DestroyRenderer(*renderer); + *renderer = NULL; + } + + if (*window != NULL) { + SDL_DestroyWindow(*window); + *window = NULL; + } +} diff --git a/drivers/display/display_sdl_bottom.h b/drivers/display/display_sdl_bottom.h new file mode 100644 index 00000000000000..91ea890c13b4d9 --- /dev/null +++ b/drivers/display/display_sdl_bottom.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2018 Jan Van Winkel + * Copyright (c) 2023 Nordic Semiconductor + * + * SPDX-License-Identifier: Apache-2.0 + * + * "Bottom" of the SDL display driver. + * When built with the native_simulator this will be built in the runner context, + * that is, with the host C library, and with the host include paths. + */ +#ifndef DRIVERS_DISPLAY_DISPLAY_SDL_BOTTOM_H +#define DRIVERS_DISPLAY_DISPLAY_SDL_BOTTOM_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Note: None of these functions are public interfaces. But internal to the SDL display driver */ + +int sdl_display_init_bottom(uint16_t height, uint16_t width, + void **window, void **renderer, void **texture); +void sdl_display_write_bottom(const uint16_t height, const uint16_t width, + const uint16_t x, const uint16_t y, + void *renderer, void *texture, + uint8_t *buf, bool display_on); +int sdl_display_read_bottom(const uint16_t height, const uint16_t width, + const uint16_t x, const uint16_t y, + void *renderer, void *buf, uint16_t pitch); +void sdl_display_blanking_off_bottom(void *renderer, void *texture); +void sdl_display_blanking_on_bottom(void *renderer); +void sdl_display_cleanup_bottom(void **window, void **renderer, void **texture); + +#ifdef __cplusplus +} +#endif + +#endif /* DRIVERS_DISPLAY_DISPLAY_SDL_BOTTOM_H */ diff --git a/drivers/gpio/CMakeLists.txt b/drivers/gpio/CMakeLists.txt index 13b4c6eba83a93..0e583053eb431c 100644 --- a/drivers/gpio/CMakeLists.txt +++ b/drivers/gpio/CMakeLists.txt @@ -45,7 +45,6 @@ zephyr_library_sources_ifdef(CONFIG_GPIO_LPC11U6X gpio_lpc11u6x.c) zephyr_library_sources_ifdef(CONFIG_GPIO_XLNX_AXI gpio_xlnx_axi.c) zephyr_library_sources_ifdef(CONFIG_GPIO_NPCX gpio_npcx.c) zephyr_library_sources_ifdef(CONFIG_GPIO_EMUL gpio_emul.c) -zephyr_library_sources_ifdef(CONFIG_GPIO_EMUL_SDL gpio_emul_sdl.c) zephyr_library_sources_ifdef(CONFIG_GPIO_PSOC6 gpio_psoc6.c) zephyr_library_sources_ifdef(CONFIG_GPIO_PCAL64XXA gpio_pcal64xxa.c) zephyr_library_sources_ifdef(CONFIG_GPIO_EOS_S3 gpio_eos_s3.c) @@ -82,6 +81,15 @@ zephyr_library_sources_ifdef(CONFIG_GPIO_HOGS gpio_hogs.c) zephyr_library_sources_ifdef(CONFIG_GPIO_NUMAKER gpio_numaker.c) zephyr_library_sources_ifdef(CONFIG_GPIO_EFINIX_SAPPHIRE gpio_efinix_sapphire.c) +if (CONFIG_GPIO_EMUL_SDL) + zephyr_library_sources(gpio_emul_sdl.c) + if (CONFIG_NATIVE_APPLICATION) + zephyr_library_sources(gpio_emul_sdl_bottom.c) + else() + target_sources(native_simulator INTERFACE gpio_emul_sdl_bottom.c) + endif() +endif() + if(CONFIG_GPIO_SC18IM704) zephyr_library_include_directories(${ZEPHYR_BASE}/drivers) zephyr_library_sources(gpio_sc18im704.c) diff --git a/drivers/gpio/gpio_emul_sdl.c b/drivers/gpio/gpio_emul_sdl.c index aa121322b91969..98d36b85779aa0 100644 --- a/drivers/gpio/gpio_emul_sdl.c +++ b/drivers/gpio/gpio_emul_sdl.c @@ -10,37 +10,29 @@ #include #include -#include +#include "gpio_emul_sdl_bottom.h" LOG_MODULE_REGISTER(gpio_emul_sdl, CONFIG_GPIO_LOG_LEVEL); struct gpio_sdl_config { const struct device *emul; - const SDL_Scancode *codes; + const int *codes; uint8_t num_codes; + struct gpio_sdl_data *data; }; -static int sdl_filter(void *arg, SDL_Event *event) +static int sdl_filter_top(struct gpio_sdl_data *bottom_data) { - const struct device *port = arg; + const struct device *port = bottom_data->dev; const struct gpio_sdl_config *config = port->config; int ret; gpio_pin_t pin = 0; - /* Only handle keyboard events */ - switch (event->type) { - case SDL_KEYDOWN: - case SDL_KEYUP: - break; - default: - return 1; - } - /* Search for the corresponding scancode */ while (pin < config->num_codes) { - if (config->codes[pin] == event->key.keysym.scancode) { + if (config->codes[pin] == bottom_data->event_scan_code) { break; } pin++; @@ -58,7 +50,7 @@ static int sdl_filter(void *arg, SDL_Event *event) k_sched_lock(); /* Update the pin state */ - ret = gpio_emul_input_set(config->emul, pin, event->type == SDL_KEYDOWN ? 1 : 0); + ret = gpio_emul_input_set(config->emul, pin, bottom_data->key_down); k_sched_unlock(); if (ret < 0) { @@ -73,13 +65,14 @@ static int gpio_sdl_init(const struct device *dev) const struct gpio_sdl_config *config = dev->config; for (uint8_t pin = 0; pin < config->num_codes; ++pin) { - if (config->codes[pin] != SDL_SCANCODE_UNKNOWN) { + if (config->codes[pin] != GPIOEMULSDL_SCANCODE_UNKNOWN) { LOG_INF("GPIO %s:%u = %u", dev->name, pin, config->codes[pin]); } } - SDL_AddEventWatch(sdl_filter, (void *)dev); - + config->data->dev = (void *)dev; + config->data->callback = sdl_filter_top; + gpio_sdl_init_bottom(config->data); return 0; } @@ -88,15 +81,18 @@ static int gpio_sdl_init(const struct device *dev) zephyr_gpio_emul, okay), \ "Enabled parent zephyr,gpio-emul node is required"); \ \ - static const SDL_Scancode gpio_sdl_##inst##_codes[] \ + static const int gpio_sdl_##inst##_codes[] \ = DT_INST_PROP(inst, scancodes); \ \ + static struct gpio_sdl_data data_##inst; \ + \ static const struct gpio_sdl_config gpio_sdl_##inst##_config = { \ .emul = DEVICE_DT_GET(DT_INST_PARENT(inst)), \ .codes = gpio_sdl_##inst##_codes, \ .num_codes = DT_INST_PROP_LEN(inst, scancodes), \ + .data = &data_##inst, \ }; \ - \ + \ DEVICE_DT_INST_DEFINE(inst, gpio_sdl_init, NULL, NULL, \ &gpio_sdl_##inst##_config, POST_KERNEL, \ CONFIG_GPIO_INIT_PRIORITY, NULL); diff --git a/drivers/gpio/gpio_emul_sdl_bottom.c b/drivers/gpio/gpio_emul_sdl_bottom.c new file mode 100644 index 00000000000000..efdcc18775dc0a --- /dev/null +++ b/drivers/gpio/gpio_emul_sdl_bottom.c @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2022, Basalte bv + * Copyright (c) 2023 Nordic Semiconductor + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include "gpio_emul_sdl_bottom.h" + +static int sdl_filter_bottom(void *arg, SDL_Event *event) +{ + struct gpio_sdl_data *data = arg; + + /* Only handle keyboard events */ + switch (event->type) { + case SDL_KEYDOWN: + case SDL_KEYUP: + break; + default: + return 1; + } + + data->event_scan_code = event->key.keysym.scancode; + data->key_down = event->type == SDL_KEYDOWN; + + return data->callback(arg); +} + +void gpio_sdl_init_bottom(struct gpio_sdl_data *data) +{ + SDL_AddEventWatch(sdl_filter_bottom, (void *)data); +} diff --git a/drivers/gpio/gpio_emul_sdl_bottom.h b/drivers/gpio/gpio_emul_sdl_bottom.h new file mode 100644 index 00000000000000..a33aec53de11e9 --- /dev/null +++ b/drivers/gpio/gpio_emul_sdl_bottom.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2022, Basalte bv + * Copyright (c) 2023 Nordic Semiconductor + * + * SPDX-License-Identifier: Apache-2.0 + * + * "Bottom" of the SDL GPIO emulator. + * When built with the native_simulator this will be built in the runner context, + * that is, with the host C library, and with the host include paths. + */ + +#ifndef DRIVERS_GPIO_GPIO_EMUL_SDL_BOTTOM_H +#define DRIVERS_GPIO_GPIO_EMUL_SDL_BOTTOM_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Note: None of these are public interfaces. But internal to the SDL GPIO emulator */ + +#define GPIOEMULSDL_SCANCODE_UNKNOWN 0 + +struct gpio_sdl_data { + void *dev; + int (*callback)(struct gpio_sdl_data *data); + int event_scan_code; + bool key_down; +}; + +void gpio_sdl_init_bottom(struct gpio_sdl_data *data); + +#ifdef __cplusplus +} +#endif + +#endif /* DRIVERS_GPIO_GPIO_EMUL_SDL_BOTTOM_H */ diff --git a/drivers/input/CMakeLists.txt b/drivers/input/CMakeLists.txt index a5483ffc764964..32280c42e1e7e0 100644 --- a/drivers/input/CMakeLists.txt +++ b/drivers/input/CMakeLists.txt @@ -7,5 +7,13 @@ zephyr_library_sources_ifdef(CONFIG_INPUT_FT5336 input_ft5336.c) zephyr_library_sources_ifdef(CONFIG_INPUT_GPIO_KEYS input_gpio_keys.c) zephyr_library_sources_ifdef(CONFIG_INPUT_GPIO_QDEC input_gpio_qdec.c) zephyr_library_sources_ifdef(CONFIG_INPUT_NPCX_KBD input_npcx_kbd.c) -zephyr_library_sources_ifdef(CONFIG_INPUT_SDL_TOUCH input_sdl_touch.c) zephyr_library_sources_ifdef(CONFIG_INPUT_XPT2046 input_xpt2046.c) + +if (CONFIG_INPUT_SDL_TOUCH) + zephyr_library_sources(input_sdl_touch.c) + if (CONFIG_NATIVE_APPLICATION) + zephyr_library_sources(input_sdl_touch_bottom.c) + else() + target_sources(native_simulator INTERFACE input_sdl_touch_bottom.c) + endif() +endif() diff --git a/drivers/input/input_sdl_touch.c b/drivers/input/input_sdl_touch.c index c1a95b75598b9f..14ed5469e17b15 100644 --- a/drivers/input/input_sdl_touch.c +++ b/drivers/input/input_sdl_touch.c @@ -1,43 +1,24 @@ /* * Copyright (c) 2020 Jabil Inc. + * Copyright (c) 2023 Nordic Semiconductor * * SPDX-License-Identifier: Apache-2.0 */ #define DT_DRV_COMPAT zephyr_input_sdl_touch +#include #include #include - -#include +#include "input_sdl_touch_bottom.h" LOG_MODULE_REGISTER(sdl_input, CONFIG_INPUT_LOG_LEVEL); -struct sdl_data { - const struct device *dev; - int x; - int y; - bool pressed; -}; - -static int sdl_filter(void *arg, SDL_Event *event) +static void sdl_input_callback(struct sdl_input_data *data) { - struct sdl_data *data = arg; - - switch (event->type) { - case SDL_MOUSEBUTTONUP: - data->pressed = false; + if (data->just_released == true) { input_report_key(data->dev, INPUT_BTN_TOUCH, 0, true, K_FOREVER); - break; - case SDL_MOUSEBUTTONDOWN: - data->pressed = true; - break; - case SDL_MOUSEMOTION: - data->x = event->button.x; - data->y = event->button.y; - break; - default: - return 1; + data->just_released = false; } if (data->pressed) { @@ -45,23 +26,22 @@ static int sdl_filter(void *arg, SDL_Event *event) input_report_abs(data->dev, INPUT_ABS_Y, data->y, false, K_FOREVER); input_report_key(data->dev, INPUT_BTN_TOUCH, 1, true, K_FOREVER); } - - return 1; } static int sdl_init(const struct device *dev) { - struct sdl_data *data = dev->data; - - data->dev = dev; + struct sdl_input_data *data = dev->data; LOG_INF("Init '%s' device", dev->name); - SDL_AddEventWatch(sdl_filter, data); + + data->dev = dev; + data->callback = sdl_input_callback; + sdl_input_init_bottom(data); return 0; } -static struct sdl_data sdl_data_0; +static struct sdl_input_data sdl_data_0; DEVICE_DT_INST_DEFINE(0, sdl_init, NULL, &sdl_data_0, NULL, POST_KERNEL, CONFIG_INPUT_INIT_PRIORITY, NULL); diff --git a/drivers/input/input_sdl_touch_bottom.c b/drivers/input/input_sdl_touch_bottom.c new file mode 100644 index 00000000000000..eb03f89ca1132b --- /dev/null +++ b/drivers/input/input_sdl_touch_bottom.c @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2020 Jabil Inc. + * Copyright (c) 2023 Nordic Semiconductor + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include "input_sdl_touch_bottom.h" + +static int sdl_filter(void *arg, SDL_Event *event) +{ + struct sdl_input_data *data = arg; + + switch (event->type) { + case SDL_MOUSEBUTTONUP: + data->pressed = false; + data->just_released = true; + break; + case SDL_MOUSEBUTTONDOWN: + data->pressed = true; + break; + case SDL_MOUSEMOTION: + data->x = event->button.x; + data->y = event->button.y; + break; + default: + return 1; + } + + data->callback(data); + + return 1; +} + +void sdl_input_init_bottom(struct sdl_input_data *data) +{ + SDL_AddEventWatch(sdl_filter, data); +} diff --git a/drivers/input/input_sdl_touch_bottom.h b/drivers/input/input_sdl_touch_bottom.h new file mode 100644 index 00000000000000..397715686ca1b7 --- /dev/null +++ b/drivers/input/input_sdl_touch_bottom.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor + * + * SPDX-License-Identifier: Apache-2.0 + * + * "Bottom" of the SDL input driver. + * When built with the native_simulator this will be built in the runner context, + * that is, with the host C library, and with the host include paths. + */ + +#ifndef DRIVERS_INPUT_INPUT_SDL_TOUCH_BOTTOM_H +#define DRIVERS_INPUT_INPUT_SDL_TOUCH_BOTTOM_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Note: None of these are public interfaces. But internal to the SDL input driver */ + +struct sdl_input_data { + const void *dev; /* device structure pointer */ + void (*callback)(struct sdl_input_data *data); + int x; + int y; + bool pressed; + bool just_released; +}; + +void sdl_input_init_bottom(struct sdl_input_data *data); + +#ifdef __cplusplus +} +#endif + +#endif /* DRIVERS_INPUT_INPUT_SDL_TOUCH_BOTTOM_H */