* update to SDL 3.2.0

* remove SDL wrap

* fix darwin and windows CI

* update build box, correct msys sdl3 dependency

* port leftovers from renderer backend to SDL3

* remove SDL main dep
the main implementation is now included in a header

* main.c: use SDL_main.h

This needs to be included to work.

* ci: use vcpkg and pkgconf to support SDL3 on MSVC

* ci: use 7z to create zip

* renwindow: create texture and surface suitable for the display

* system: remove trailing whitespace

* renderer: fix trailing whitespace

* system: fix checking the wrong argument

* system: port rmdir and stat to SDL3 API

* system: remove unneeded API level check

* system: fix wrong parameter index

* system: make set_window_hit_test and set_window_bordered accept a window

* docs/system: update docs

* system: restore some comments

* docs/system: add missing documentation for system.text_input

* system: use SDL_setenv_unsafe

* system: add back comment for setenv

* system,renderer: remove unnecessary SDL_ClearError calls

---------

Co-authored-by: takase1121 <20792268+takase1121@users.noreply.github.com>
(cherry picked from commit 2716f14b6903f055f6bdf010a7e4a3d040cf059d)
This commit is contained in:
takase1121
2025-05-18 22:55:30 +08:00
parent 16d81d0b9c
commit bb05cf3e4d
15 changed files with 338 additions and 446 deletions
+39 -10
View File
@@ -19,7 +19,8 @@ jobs:
matrix: matrix:
config: config:
- { name: "GCC", cc: gcc, cxx: g++ } - { name: "GCC", cc: gcc, cxx: g++ }
- { name: "clang", cc: clang, cxx: clang++ } # disable this until we have clang in the build box
# - { name: "clang", cc: clang, cxx: clang++ }
env: env:
CC: ${{ matrix.config.cc }} CC: ${{ matrix.config.cc }}
CXX: ${{ matrix.config.cxx }} CXX: ${{ matrix.config.cxx }}
@@ -35,19 +36,28 @@ jobs:
- name: Checkout code - name: Checkout code
uses: actions/checkout@v4 uses: actions/checkout@v4
# disabled because this will break our own Python install
- name: Python Setup - name: Python Setup
if: false
uses: actions/setup-python@v5 uses: actions/setup-python@v5
with: with:
python-version: "3.11" python-version: "3.11"
# disabled because the container has up-to-date packages
- name: Update Packages - name: Update Packages
if: false
run: sudo apt-get update run: sudo apt-get update
# disabled as the dependencies are already installed
- name: Install Dependencies - name: Install Dependencies
if: false
run: bash scripts/install-dependencies.sh --debug run: bash scripts/install-dependencies.sh --debug
- name: Build - name: Build
run: | uses: docker://ghcr.io/lite-xl/lite-xl-build-box-manylinux:v4
with:
entrypoint: /entrypoint.sh
args: |
bash --version bash --version
bash scripts/build.sh --debug --forcefallback --portable bash scripts/build.sh --debug --forcefallback --portable
@@ -101,7 +111,7 @@ jobs:
# installing md5sha1sum will eliminate a warning with arm64 and libusb # installing md5sha1sum will eliminate a warning with arm64 and libusb
- name: Install Dependencies - name: Install Dependencies
run: | run: |
brew install bash md5sha1sum brew install bash md5sha1sum sdl3
pip install meson ninja dmgbuild pip install meson ninja dmgbuild
- name: Build - name: Build
@@ -192,11 +202,14 @@ jobs:
base-devel base-devel
git git
zip zip
mingw-w64-${{ matrix.config.arch }}-gcc patch
mingw-w64-${{ matrix.config.arch }}-meson pacboy: >-
mingw-w64-${{ matrix.config.arch }}-ninja gcc:p
mingw-w64-${{ matrix.config.arch }}-ca-certificates meson:p
mingw-w64-${{ matrix.config.arch }}-ntldd ca-certificates:p
ninja:p
pkg-config:p
sdl3:p
- name: Set Environment Variables - name: Set Environment Variables
run: | run: |
@@ -251,7 +264,23 @@ jobs:
python-version: "3.11" python-version: "3.11"
- name: Install meson and ninja - name: Install meson and ninja
run: pip install meson ninja run: pip install --no-cache-dir meson ninja
- name: Export GitHub Actions cache environment variables
uses: actions/github-script@v7
with:
script: |
core.exportVariable('ACTIONS_CACHE_URL', process.env.ACTIONS_CACHE_URL || '');
core.exportVariable('ACTIONS_RUNTIME_TOKEN', process.env.ACTIONS_RUNTIME_TOKEN || '');
- name: Install SDL
env: { VCPKG_BINARY_SOURCES: "clear;x-gha,readwrite" }
run: vcpkg install sdl3:x64-windows-static pkgconf:x64-windows-release
- name: Add environment variables
run: |
echo "PKG_CONFIG_PATH=C:\vcpkg\installed\x64-windows-static\lib\pkgconfig" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
echo "PKG_CONFIG=C:\vcpkg\installed\x64-windows-release\tools\pkgconf\pkgconf.exe" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
- name: Set up environment variables - name: Set up environment variables
run: | run: |
@@ -276,7 +305,7 @@ jobs:
- name: Package - name: Package
run: | run: |
Remove-Item -Recurse -Force -Path "lite-xl/lib","lite-xl/include" Remove-Item -Recurse -Force -Path "lite-xl/lib","lite-xl/include"
Compress-Archive -Path lite-xl -DestinationPath "$env:INSTALL_NAME.zip" 7z a -mx=9 "$env:INSTALL_NAME.zip" lite-xl
- name: Upload Artifacts - name: Upload Artifacts
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
+12 -9
View File
@@ -92,7 +92,7 @@ jobs:
sudo apt-get install -y ccache sudo apt-get install -y ccache
- name: Build Portable - name: Build Portable
uses: docker://ghcr.io/lite-xl/lite-xl-build-box-manylinux:v3 uses: docker://ghcr.io/lite-xl/lite-xl-build-box-manylinux:v4
with: with:
entrypoint: /entrypoint.sh entrypoint: /entrypoint.sh
args: | args: |
@@ -100,7 +100,7 @@ jobs:
bash scripts/build.sh --debug --forcefallback --portable --release --lto bash scripts/build.sh --debug --forcefallback --portable --release --lto
- name: Package Portables - name: Package Portables
uses: docker://ghcr.io/lite-xl/lite-xl-build-box-manylinux:v3 uses: docker://ghcr.io/lite-xl/lite-xl-build-box-manylinux:v4
with: with:
entrypoint: /entrypoint.sh entrypoint: /entrypoint.sh
args: | args: |
@@ -108,7 +108,7 @@ jobs:
bash scripts/package.sh --version ${INSTALL_REF} --debug --addons --binary --release bash scripts/package.sh --version ${INSTALL_REF} --debug --addons --binary --release
- name: Build AppImages - name: Build AppImages
uses: docker://ghcr.io/lite-xl/lite-xl-build-box-manylinux:v3 uses: docker://ghcr.io/lite-xl/lite-xl-build-box-manylinux:v4
with: with:
entrypoint: /entrypoint.sh entrypoint: /entrypoint.sh
args: | args: |
@@ -164,7 +164,7 @@ jobs:
- name: Install Dependencies - name: Install Dependencies
run: | run: |
brew install bash md5sha1sum brew install bash md5sha1sum sdl3
pip install meson ninja dmgbuild pip install meson ninja dmgbuild
- name: Build - name: Build
@@ -269,11 +269,14 @@ jobs:
git git
zip zip
unzip unzip
mingw-w64-${{ matrix.config.arch }}-gcc patch
mingw-w64-${{ matrix.config.arch }}-meson pacboy: >-
mingw-w64-${{ matrix.config.arch }}-ninja gcc:p
mingw-w64-${{ matrix.config.arch }}-ca-certificates meson:p
mingw-w64-${{ matrix.config.arch }}-ntldd ca-certificates:p
ninja:p
pkg-config:p
sdl3:p
- name: Set Environment Variables - name: Set Environment Variables
run: | run: |
+1 -1
View File
@@ -43,7 +43,7 @@ conf_data.set('PROJECT_ASSEMBLY_VERSION', meson.project_version() + '.0')
cc = meson.get_compiler('c') cc = meson.get_compiler('c')
lite_includes = [] lite_includes = []
lite_cargs = ['-DSDL_MAIN_HANDLED', '-DPCRE2_STATIC'] lite_cargs = ['-DPCRE2_STATIC']
# On macos we need to use the SDL renderer to support retina displays # On macos we need to use the SDL renderer to support retina displays
if get_option('renderer') or host_machine.system() == 'darwin' if get_option('renderer') or host_machine.system() == 'darwin'
lite_cargs += '-DLITE_USE_SDL_RENDERER' lite_cargs += '-DLITE_USE_SDL_RENDERER'
+2 -2
View File
@@ -1,6 +1,6 @@
#include "api.h" #include "api.h"
#include "lua.h" #include "lua.h"
#include <SDL.h> #include <SDL3/SDL.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <stdbool.h> #include <stdbool.h>
@@ -9,7 +9,7 @@ static unsigned int DIR_EVENT_TYPE = 0;
struct dirmonitor { struct dirmonitor {
SDL_Thread* thread; SDL_Thread* thread;
SDL_mutex* mutex; SDL_Mutex* mutex;
char buffer[64512]; char buffer[64512];
volatile int length; volatile int length;
struct dirmonitor_internal* internal; struct dirmonitor_internal* internal;
+2 -2
View File
@@ -1,8 +1,8 @@
#include <SDL.h> #include <SDL3/SDL.h>
#include <CoreServices/CoreServices.h> #include <CoreServices/CoreServices.h>
struct dirmonitor_internal { struct dirmonitor_internal {
SDL_mutex* lock; SDL_Mutex* lock;
char** changes; char** changes;
size_t count; size_t count;
FSEventStreamRef stream; FSEventStreamRef stream;
+13 -13
View File
@@ -4,8 +4,8 @@
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#include <stdlib.h> #include <stdlib.h>
#include <SDL.h> #include <SDL3/SDL.h>
#include <SDL_thread.h> #include <SDL3/SDL_thread.h>
#include <assert.h> #include <assert.h>
#if _WIN32 #if _WIN32
@@ -85,8 +85,8 @@ typedef struct process_kill_s {
typedef struct { typedef struct {
bool stop; bool stop;
SDL_mutex *mutex; SDL_Mutex *mutex;
SDL_cond *has_work, *work_done; SDL_Condition *has_work, *work_done;
SDL_Thread *worker_thread; SDL_Thread *worker_thread;
process_kill_t *head; process_kill_t *head;
process_kill_t *tail; process_kill_t *tail;
@@ -133,8 +133,8 @@ static void kill_list_free(process_kill_list_t *list) {
process_kill_t *node, *temp; process_kill_t *node, *temp;
SDL_WaitThread(list->worker_thread, NULL); SDL_WaitThread(list->worker_thread, NULL);
SDL_DestroyMutex(list->mutex); SDL_DestroyMutex(list->mutex);
SDL_DestroyCond(list->has_work); SDL_DestroyCondition(list->has_work);
SDL_DestroyCond(list->work_done); SDL_DestroyCondition(list->work_done);
node = list->head; node = list->head;
while (node) { while (node) {
temp = node; temp = node;
@@ -148,8 +148,8 @@ static void kill_list_free(process_kill_list_t *list) {
static bool kill_list_init(process_kill_list_t *list) { static bool kill_list_init(process_kill_list_t *list) {
memset(list, 0, sizeof(process_kill_list_t)); memset(list, 0, sizeof(process_kill_list_t));
list->mutex = SDL_CreateMutex(); list->mutex = SDL_CreateMutex();
list->has_work = SDL_CreateCond(); list->has_work = SDL_CreateCondition();
list->work_done = SDL_CreateCond(); list->work_done = SDL_CreateCondition();
list->head = list->tail = NULL; list->head = list->tail = NULL;
list->stop = false; list->stop = false;
if (!list->mutex || !list->has_work || !list->work_done) { if (!list->mutex || !list->has_work || !list->work_done) {
@@ -190,10 +190,10 @@ static void kill_list_wait_all(process_kill_list_t *list) {
SDL_LockMutex(list->mutex); SDL_LockMutex(list->mutex);
// wait until list is empty // wait until list is empty
while (list->head) while (list->head)
SDL_CondWait(list->work_done, list->mutex); SDL_WaitCondition(list->work_done, list->mutex);
// tell the worker to stop // tell the worker to stop
list->stop = true; list->stop = true;
SDL_CondSignal(list->has_work); SDL_SignalCondition(list->has_work);
SDL_UnlockMutex(list->mutex); SDL_UnlockMutex(list->mutex);
} }
@@ -257,7 +257,7 @@ static int kill_list_worker(void *ud) {
// wait until we have work to do // wait until we have work to do
while (!list->head && !list->stop) while (!list->head && !list->stop)
SDL_CondWait(list->has_work, list->mutex); // LOCK MUTEX SDL_WaitCondition(list->has_work, list->mutex); // LOCK MUTEX
if (list->stop) break; if (list->stop) break;
@@ -279,7 +279,7 @@ static int kill_list_worker(void *ud) {
kill_list_push(list, current_task); kill_list_push(list, current_task);
} else { } else {
free_task: free_task:
SDL_CondSignal(list->work_done); SDL_SignalCondition(list->work_done);
process_handle_close(&current_task->handle); process_handle_close(&current_task->handle);
free(current_task); free(current_task);
} }
@@ -759,7 +759,7 @@ static int f_gc(lua_State* L) {
p->tries = 1; p->tries = 1;
SDL_LockMutex(list->mutex); SDL_LockMutex(list->mutex);
kill_list_push(list, p); kill_list_push(list, p);
SDL_CondSignal(list->has_work); SDL_SignalCondition(list->has_work);
SDL_UnlockMutex(list->mutex); SDL_UnlockMutex(list->mutex);
} }
} }
+109 -173
View File
@@ -1,4 +1,5 @@
#include <SDL.h> #include <SDL3/SDL.h>
#include <stdlib.h>
#include <string.h> #include <string.h>
#include <stdbool.h> #include <stdbool.h>
#include <stdlib.h> #include <stdlib.h>
@@ -117,12 +118,12 @@ static SDL_HitTestResult SDLCALL hit_test(SDL_Window *window, const SDL_Point *p
static const char *numpad[] = { "end", "down", "pagedown", "left", "", "right", "home", "up", "pageup", "ins", "delete" }; static const char *numpad[] = { "end", "down", "pagedown", "left", "", "right", "home", "up", "pageup", "ins", "delete" };
static const char *get_key_name(const SDL_Event *e, char *buf) { static const char *get_key_name(const SDL_Event *e, char *buf) {
SDL_Scancode scancode = e->key.keysym.scancode; SDL_Scancode scancode = e->key.scancode;
/* Is the scancode from the keypad and the number-lock off? /* Is the scancode from the keypad and the number-lock off?
** We assume that SDL_SCANCODE_KP_1 up to SDL_SCANCODE_KP_9 and SDL_SCANCODE_KP_0 ** We assume that SDL_SCANCODE_KP_1 up to SDL_SCANCODE_KP_9 and SDL_SCANCODE_KP_0
** and SDL_SCANCODE_KP_PERIOD are declared in SDL2 in that order. */ ** and SDL_SCANCODE_KP_PERIOD are declared in SDL2 in that order. */
if (scancode >= SDL_SCANCODE_KP_1 && scancode <= SDL_SCANCODE_KP_1 + 10 && if (scancode >= SDL_SCANCODE_KP_1 && scancode <= SDL_SCANCODE_KP_1 + 10 &&
!(e->key.keysym.mod & KMOD_NUM)) { !(e->key.mod & SDL_KMOD_NUM)) {
return numpad[scancode - SDL_SCANCODE_KP_1]; return numpad[scancode - SDL_SCANCODE_KP_1];
} else { } else {
/* We need to correctly handle non-standard layouts such as dvorak. /* We need to correctly handle non-standard layouts such as dvorak.
@@ -135,8 +136,8 @@ static const char *get_key_name(const SDL_Event *e, char *buf) {
and others, are masked with SDLK_SCANCODE_MASK, which moves them outside and others, are masked with SDLK_SCANCODE_MASK, which moves them outside
the unicode range (>0x10FFFF). Users can remap these buttons, so we need the unicode range (>0x10FFFF). Users can remap these buttons, so we need
to return the correct name, not scancode based. */ to return the correct name, not scancode based. */
if ((e->key.keysym.sym < 128) || (e->key.keysym.sym & SDLK_SCANCODE_MASK)) if ((e->key.key < 128) || (e->key.key & SDLK_SCANCODE_MASK))
strcpy(buf, SDL_GetKeyName(e->key.keysym.sym)); strcpy(buf, SDL_GetKeyName(e->key.key));
else else
strcpy(buf, SDL_GetScancodeName(scancode)); strcpy(buf, SDL_GetScancodeName(scancode));
str_tolower(buf); str_tolower(buf);
@@ -171,7 +172,8 @@ static void push_win32_error(lua_State *L, DWORD rc) {
static int f_poll_event(lua_State *L) { static int f_poll_event(lua_State *L) {
char buf[16]; char buf[16];
int mx, my, w, h; float mx, my;
int w, h;
SDL_Event e; SDL_Event e;
SDL_Event event_plus; SDL_Event event_plus;
@@ -181,106 +183,104 @@ top:
} }
switch (e.type) { switch (e.type) {
case SDL_QUIT: case SDL_EVENT_QUIT:
lua_pushstring(L, "quit"); lua_pushstring(L, "quit");
return 1; return 1;
case SDL_WINDOWEVENT: case SDL_EVENT_WINDOW_RESIZED:
if (e.window.event == SDL_WINDOWEVENT_RESIZED) { {
ren_resize_window(&window_renderer); ren_resize_window(&window_renderer);
lua_pushstring(L, "resized"); lua_pushstring(L, "resized");
/* The size below will be in points. */ /* The size below will be in points. */
lua_pushinteger(L, e.window.data1); lua_pushinteger(L, e.window.data1);
lua_pushinteger(L, e.window.data2); lua_pushinteger(L, e.window.data2);
return 3; return 3;
} else if (e.window.event == SDL_WINDOWEVENT_EXPOSED) { }
case SDL_EVENT_WINDOW_EXPOSED:
rencache_invalidate(); rencache_invalidate();
lua_pushstring(L, "exposed"); lua_pushstring(L, "exposed");
return 1; return 1;
} else if (e.window.event == SDL_WINDOWEVENT_MINIMIZED) {
case SDL_EVENT_WINDOW_MINIMIZED:
lua_pushstring(L, "minimized"); lua_pushstring(L, "minimized");
return 1; return 1;
} else if (e.window.event == SDL_WINDOWEVENT_MAXIMIZED) {
case SDL_EVENT_WINDOW_MAXIMIZED:
lua_pushstring(L, "maximized"); lua_pushstring(L, "maximized");
return 1; return 1;
} else if (e.window.event == SDL_WINDOWEVENT_RESTORED) {
case SDL_EVENT_WINDOW_RESTORED:
lua_pushstring(L, "restored"); lua_pushstring(L, "restored");
return 1; return 1;
} else if (e.window.event == SDL_WINDOWEVENT_LEAVE) {
case SDL_EVENT_WINDOW_MOUSE_LEAVE:
lua_pushstring(L, "mouseleft"); lua_pushstring(L, "mouseleft");
return 1; return 1;
}
if (e.window.event == SDL_WINDOWEVENT_FOCUS_LOST) { case SDL_EVENT_WINDOW_FOCUS_LOST:
lua_pushstring(L, "focuslost"); lua_pushstring(L, "focuslost");
return 1; return 1;
}
case SDL_EVENT_WINDOW_FOCUS_GAINED:
/* on some systems, when alt-tabbing to the window SDL will queue up /* on some systems, when alt-tabbing to the window SDL will queue up
** several KEYDOWN events for the `tab` key; we flush all keydown ** several KEYDOWN events for the `tab` key; we flush all keydown
** events on focus so these are discarded */ ** events on focus so these are discarded */
if (e.window.event == SDL_WINDOWEVENT_FOCUS_GAINED) { SDL_FlushEvent(SDL_EVENT_KEY_DOWN);
SDL_FlushEvent(SDL_KEYDOWN);
}
goto top; goto top;
case SDL_DROPFILE:
case SDL_EVENT_DROP_FILE:
{
SDL_GetMouseState(&mx, &my); SDL_GetMouseState(&mx, &my);
lua_pushstring(L, "filedropped"); lua_pushstring(L, "filedropped");
lua_pushstring(L, e.drop.file); lua_pushstring(L, e.drop.data);
lua_pushinteger(L, mx * window_renderer.scale_x); lua_pushinteger(L, mx * window_renderer.scale_x);
lua_pushinteger(L, my * window_renderer.scale_y); lua_pushinteger(L, my * window_renderer.scale_y);
SDL_free(e.drop.file);
return 4; return 4;
}
case SDL_KEYDOWN: case SDL_EVENT_KEY_DOWN:
#ifdef __APPLE__ #ifdef __APPLE__
/* on macos 11.2.3 with sdl 2.0.14 the keyup handler for cmd+w below /* on macos 11.2.3 with sdl 2.0.14 the keyup handler for cmd+w below
** was not enough. Maybe the quit event started to be triggered from the ** was not enough. Maybe the quit event started to be triggered from the
** keydown handler? In any case, flushing the quit event here too helped. */ ** keydown handler? In any case, flushing the quit event here too helped. */
if ((e.key.keysym.sym == SDLK_w) && (e.key.keysym.mod & KMOD_GUI)) { if ((e.key.key == SDLK_W) && (e.key.mod & SDL_KMOD_GUI)) {
SDL_FlushEvent(SDL_QUIT); SDL_FlushEvent(SDL_EVENT_QUIT);
} }
#endif #endif
lua_pushstring(L, "keypressed"); lua_pushstring(L, "keypressed");
lua_pushstring(L, get_key_name(&e, buf)); lua_pushstring(L, get_key_name(&e, buf));
return 2; return 2;
case SDL_KEYUP: case SDL_EVENT_KEY_UP:
#ifdef __APPLE__ #ifdef __APPLE__
/* on macos command+w will close the current window /* on macos command+w will close the current window
** we want to flush this event and let the keymapper ** we want to flush this event and let the keymapper
** handle this key combination. ** handle this key combination.
** Thanks to mathewmariani, taken from his lite-macos github repository. */ ** Thanks to mathewmariani, taken from his lite-macos github repository. */
if ((e.key.keysym.sym == SDLK_w) && (e.key.keysym.mod & KMOD_GUI)) { if ((e.key.key == SDLK_W) && (e.key.mod & SDL_KMOD_GUI)) {
SDL_FlushEvent(SDL_QUIT); SDL_FlushEvent(SDL_EVENT_QUIT);
} }
#endif #endif
lua_pushstring(L, "keyreleased"); lua_pushstring(L, "keyreleased");
lua_pushstring(L, get_key_name(&e, buf)); lua_pushstring(L, get_key_name(&e, buf));
return 2; return 2;
case SDL_TEXTINPUT: case SDL_EVENT_TEXT_INPUT:
lua_pushstring(L, "textinput"); lua_pushstring(L, "textinput");
lua_pushstring(L, e.text.text); lua_pushstring(L, e.text.text);
return 2; return 2;
case SDL_TEXTEDITING: case SDL_EVENT_TEXT_EDITING:
lua_pushstring(L, "textediting"); lua_pushstring(L, "textediting");
lua_pushstring(L, e.edit.text); lua_pushstring(L, e.edit.text);
lua_pushinteger(L, e.edit.start); lua_pushinteger(L, e.edit.start);
lua_pushinteger(L, e.edit.length); lua_pushinteger(L, e.edit.length);
return 4; return 4;
#if SDL_VERSION_ATLEAST(2, 0, 22) case SDL_EVENT_MOUSE_BUTTON_DOWN:
case SDL_TEXTEDITING_EXT: {
lua_pushstring(L, "textediting");
lua_pushstring(L, e.editExt.text);
lua_pushinteger(L, e.editExt.start);
lua_pushinteger(L, e.editExt.length);
SDL_free(e.editExt.text);
return 4;
#endif
case SDL_MOUSEBUTTONDOWN:
if (e.button.button == 1) { SDL_CaptureMouse(1); } if (e.button.button == 1) { SDL_CaptureMouse(1); }
lua_pushstring(L, "mousepressed"); lua_pushstring(L, "mousepressed");
lua_pushstring(L, button_name(e.button.button)); lua_pushstring(L, button_name(e.button.button));
@@ -288,18 +288,22 @@ top:
lua_pushinteger(L, e.button.y * window_renderer.scale_y); lua_pushinteger(L, e.button.y * window_renderer.scale_y);
lua_pushinteger(L, e.button.clicks); lua_pushinteger(L, e.button.clicks);
return 5; return 5;
}
case SDL_MOUSEBUTTONUP: case SDL_EVENT_MOUSE_BUTTON_UP:
{
if (e.button.button == 1) { SDL_CaptureMouse(0); } if (e.button.button == 1) { SDL_CaptureMouse(0); }
lua_pushstring(L, "mousereleased"); lua_pushstring(L, "mousereleased");
lua_pushstring(L, button_name(e.button.button)); lua_pushstring(L, button_name(e.button.button));
lua_pushinteger(L, e.button.x * window_renderer.scale_x); lua_pushinteger(L, e.button.x * window_renderer.scale_x);
lua_pushinteger(L, e.button.y * window_renderer.scale_y); lua_pushinteger(L, e.button.y * window_renderer.scale_y);
return 4; return 4;
}
case SDL_MOUSEMOTION: case SDL_EVENT_MOUSE_MOTION:
{
SDL_PumpEvents(); SDL_PumpEvents();
while (SDL_PeepEvents(&event_plus, 1, SDL_GETEVENT, SDL_MOUSEMOTION, SDL_MOUSEMOTION) > 0) { while (SDL_PeepEvents(&event_plus, 1, SDL_GETEVENT, SDL_EVENT_MOUSE_MOTION, SDL_EVENT_MOUSE_MOTION) > 0) {
e.motion.x = event_plus.motion.x; e.motion.x = event_plus.motion.x;
e.motion.y = event_plus.motion.y; e.motion.y = event_plus.motion.y;
e.motion.xrel += event_plus.motion.xrel; e.motion.xrel += event_plus.motion.xrel;
@@ -311,40 +315,41 @@ top:
lua_pushinteger(L, e.motion.xrel * window_renderer.scale_x); lua_pushinteger(L, e.motion.xrel * window_renderer.scale_x);
lua_pushinteger(L, e.motion.yrel * window_renderer.scale_y); lua_pushinteger(L, e.motion.yrel * window_renderer.scale_y);
return 5; return 5;
}
case SDL_MOUSEWHEEL: case SDL_EVENT_MOUSE_WHEEL:
lua_pushstring(L, "mousewheel"); lua_pushstring(L, "mousewheel");
#if SDL_VERSION_ATLEAST(2, 0, 18) lua_pushnumber(L, e.wheel.y);
lua_pushnumber(L, e.wheel.preciseY);
// Use -x to keep consistency with vertical scrolling values (e.g. shift+scroll) // Use -x to keep consistency with vertical scrolling values (e.g. shift+scroll)
lua_pushnumber(L, -e.wheel.preciseX); lua_pushnumber(L, -e.wheel.x);
#else
lua_pushinteger(L, e.wheel.y);
lua_pushinteger(L, -e.wheel.x);
#endif
return 3; return 3;
case SDL_FINGERDOWN: case SDL_EVENT_FINGER_DOWN:
{
SDL_GetWindowSize(window_renderer.window, &w, &h); SDL_GetWindowSize(window_renderer.window, &w, &h);
lua_pushstring(L, "touchpressed"); lua_pushstring(L, "touchpressed");
lua_pushinteger(L, (lua_Integer)(e.tfinger.x * w)); lua_pushinteger(L, (lua_Integer)(e.tfinger.x * w));
lua_pushinteger(L, (lua_Integer)(e.tfinger.y * h)); lua_pushinteger(L, (lua_Integer)(e.tfinger.y * h));
lua_pushinteger(L, e.tfinger.fingerId); lua_pushinteger(L, e.tfinger.fingerID);
return 4; return 4;
}
case SDL_FINGERUP: case SDL_EVENT_FINGER_UP:
{
SDL_GetWindowSize(window_renderer.window, &w, &h); SDL_GetWindowSize(window_renderer.window, &w, &h);
lua_pushstring(L, "touchreleased"); lua_pushstring(L, "touchreleased");
lua_pushinteger(L, (lua_Integer)(e.tfinger.x * w)); lua_pushinteger(L, (lua_Integer)(e.tfinger.x * w));
lua_pushinteger(L, (lua_Integer)(e.tfinger.y * h)); lua_pushinteger(L, (lua_Integer)(e.tfinger.y * h));
lua_pushinteger(L, e.tfinger.fingerId); lua_pushinteger(L, e.tfinger.fingerID);
return 4; return 4;
}
case SDL_FINGERMOTION: case SDL_EVENT_FINGER_MOTION:
{
SDL_PumpEvents(); SDL_PumpEvents();
while (SDL_PeepEvents(&event_plus, 1, SDL_GETEVENT, SDL_FINGERMOTION, SDL_FINGERMOTION) > 0) { while (SDL_PeepEvents(&event_plus, 1, SDL_GETEVENT, SDL_EVENT_FINGER_MOTION, SDL_EVENT_FINGER_MOTION) > 0) {
e.tfinger.x = event_plus.tfinger.x; e.tfinger.x = event_plus.tfinger.x;
e.tfinger.y = event_plus.tfinger.y; e.tfinger.y = event_plus.tfinger.y;
e.tfinger.dx += event_plus.tfinger.dx; e.tfinger.dx += event_plus.tfinger.dx;
@@ -357,8 +362,26 @@ top:
lua_pushinteger(L, (lua_Integer)(e.tfinger.y * h)); lua_pushinteger(L, (lua_Integer)(e.tfinger.y * h));
lua_pushinteger(L, (lua_Integer)(e.tfinger.dx * w)); lua_pushinteger(L, (lua_Integer)(e.tfinger.dx * w));
lua_pushinteger(L, (lua_Integer)(e.tfinger.dy * h)); lua_pushinteger(L, (lua_Integer)(e.tfinger.dy * h));
lua_pushinteger(L, e.tfinger.fingerId); lua_pushinteger(L, e.tfinger.fingerID);
return 6; return 6;
}
case SDL_EVENT_WILL_ENTER_FOREGROUND:
case SDL_EVENT_DID_ENTER_FOREGROUND:
{
#ifdef LITE_USE_SDL_RENDERER
rencache_invalidate();
#else
SDL_UpdateWindowSurface(window_renderer.window);
#endif
lua_pushstring(L, e.type == SDL_EVENT_WILL_ENTER_FOREGROUND ? "enteringforeground" : "enteredforeground");
return 1;
}
case SDL_EVENT_WILL_ENTER_BACKGROUND:
lua_pushstring(L, "enteringbackground");
return 1;
case SDL_EVENT_DID_ENTER_BACKGROUND:
lua_pushstring(L, "enteredbackground");
return 1;
default: default:
goto top; goto top;
@@ -381,7 +404,7 @@ static int f_wait_event(lua_State *L) {
} }
static SDL_Cursor* cursor_cache[SDL_SYSTEM_CURSOR_HAND + 1]; static SDL_Cursor* cursor_cache[SDL_SYSTEM_CURSOR_POINTER + 1];
static const char *cursor_opts[] = { static const char *cursor_opts[] = {
"arrow", "arrow",
@@ -393,11 +416,11 @@ static const char *cursor_opts[] = {
}; };
static const int cursor_enums[] = { static const int cursor_enums[] = {
SDL_SYSTEM_CURSOR_ARROW, SDL_SYSTEM_CURSOR_DEFAULT,
SDL_SYSTEM_CURSOR_IBEAM, SDL_SYSTEM_CURSOR_TEXT,
SDL_SYSTEM_CURSOR_SIZEWE, SDL_SYSTEM_CURSOR_EW_RESIZE,
SDL_SYSTEM_CURSOR_SIZENS, SDL_SYSTEM_CURSOR_NS_RESIZE,
SDL_SYSTEM_CURSOR_HAND SDL_SYSTEM_CURSOR_POINTER
}; };
static int f_set_cursor(lua_State *L) { static int f_set_cursor(lua_State *L) {
@@ -425,8 +448,7 @@ enum { WIN_NORMAL, WIN_MINIMIZED, WIN_MAXIMIZED, WIN_FULLSCREEN };
static int f_set_window_mode(lua_State *L) { static int f_set_window_mode(lua_State *L) {
int n = luaL_checkoption(L, 1, "normal", window_opts); int n = luaL_checkoption(L, 1, "normal", window_opts);
SDL_SetWindowFullscreen(window_renderer.window, SDL_SetWindowFullscreen(window_renderer.window, n == WIN_FULLSCREEN);
n == WIN_FULLSCREEN ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0);
if (n == WIN_NORMAL) { SDL_RestoreWindow(window_renderer.window); } if (n == WIN_NORMAL) { SDL_RestoreWindow(window_renderer.window); }
if (n == WIN_MAXIMIZED) { SDL_MaximizeWindow(window_renderer.window); } if (n == WIN_MAXIMIZED) { SDL_MaximizeWindow(window_renderer.window); }
if (n == WIN_MINIMIZED) { SDL_MinimizeWindow(window_renderer.window); } if (n == WIN_MINIMIZED) { SDL_MinimizeWindow(window_renderer.window); }
@@ -435,21 +457,20 @@ static int f_set_window_mode(lua_State *L) {
static int f_set_window_bordered(lua_State *L) { static int f_set_window_bordered(lua_State *L) {
int bordered = lua_toboolean(L, 1); SDL_SetWindowBordered(window_renderer.window, lua_toboolean(L, 1));
SDL_SetWindowBordered(window_renderer.window, bordered);
return 0; return 0;
} }
static int f_set_window_hit_test(lua_State *L) { static int f_set_window_hit_test(lua_State *L) {
if (lua_gettop(L) == 0) { if (lua_isnoneornil(L, 1)) {
SDL_SetWindowHitTest(window_renderer.window, NULL, NULL); SDL_SetWindowHitTest(window_renderer.window, NULL, NULL);
return 0; return 0;
} }
window_hit_info->title_height = luaL_checknumber(L, 1); window_hit_info->title_height = luaL_checknumber(L, 1);
window_hit_info->controls_width = luaL_checknumber(L, 2); window_hit_info->controls_width = luaL_checknumber(L, 2);
window_hit_info->resize_border = luaL_checknumber(L, 3); window_hit_info->resize_border = luaL_checknumber(L, 3);
SDL_SetWindowHitTest(window_renderer.window, hit_test, window_hit_info); SDL_SetWindowHitTest(window_renderer.window, &hit_test, window_hit_info);
return 0; return 0;
} }
@@ -487,7 +508,7 @@ static int f_window_has_focus(lua_State *L) {
static int f_get_window_mode(lua_State *L) { static int f_get_window_mode(lua_State *L) {
unsigned flags = SDL_GetWindowFlags(window_renderer.window); unsigned flags = SDL_GetWindowFlags(window_renderer.window);
if (flags & SDL_WINDOW_FULLSCREEN_DESKTOP) { if (flags & SDL_WINDOW_FULLSCREEN) {
lua_pushstring(L, "fullscreen"); lua_pushstring(L, "fullscreen");
} else if (flags & SDL_WINDOW_MINIMIZED) { } else if (flags & SDL_WINDOW_MINIMIZED) {
lua_pushstring(L, "minimized"); lua_pushstring(L, "minimized");
@@ -505,26 +526,17 @@ static int f_set_text_input_rect(lua_State *L) {
rect.y = luaL_checknumber(L, 2); rect.y = luaL_checknumber(L, 2);
rect.w = luaL_checknumber(L, 3); rect.w = luaL_checknumber(L, 3);
rect.h = luaL_checknumber(L, 4); rect.h = luaL_checknumber(L, 4);
SDL_SetTextInputRect(&rect); SDL_SetTextInputArea(window_renderer.window, &rect, 0);
return 0; return 0;
} }
static int f_clear_ime(lua_State *L) { static int f_clear_ime(lua_State *L) {
#if SDL_VERSION_ATLEAST(2, 0, 22) SDL_ClearComposition(window_renderer.window);
SDL_ClearComposition();
#endif
return 0; return 0;
} }
static int f_raise_window(lua_State *L) { static int f_raise_window(lua_State *L) {
/*
SDL_RaiseWindow should be enough but on some window managers like the
one used on Gnome the window needs to first have input focus in order
to allow the window to be focused. Also on wayland the raise window event
may not always be obeyed.
*/
SDL_SetWindowInputFocus(window_renderer.window);
SDL_RaiseWindow(window_renderer.window); SDL_RaiseWindow(window_renderer.window);
return 0; return 0;
} }
@@ -545,31 +557,11 @@ static int f_show_fatal_error(lua_State *L) {
// removes an empty directory // removes an empty directory
static int f_rmdir(lua_State *L) { static int f_rmdir(lua_State *L) {
const char *path = luaL_checkstring(L, 1); lua_pushboolean(L, SDL_RemovePath(luaL_checkstring(L, 1)));
if (!lua_toboolean(L, -1)) {
#ifdef _WIN32 lua_pushstring(L, SDL_GetError());
LPWSTR wpath = utfconv_utf8towc(path);
int deleted = RemoveDirectoryW(wpath);
free(wpath);
if (deleted > 0) {
lua_pushboolean(L, 1);
} else {
lua_pushboolean(L, 0);
push_win32_error(L, GetLastError());
return 2; return 2;
} }
#else
int deleted = remove(path);
if(deleted < 0) {
lua_pushboolean(L, 0);
lua_pushstring(L, strerror(errno));
return 2;
} else {
lua_pushboolean(L, 1);
}
#endif
return 1; return 1;
} }
@@ -590,80 +582,24 @@ static int f_chdir(lua_State *L) {
static int f_list_dir(lua_State *L) { static int f_list_dir(lua_State *L) {
int count = 0;
const char *path = luaL_checkstring(L, 1); const char *path = luaL_checkstring(L, 1);
char **dir = SDL_GlobDirectory(path, NULL, 0, &count);
#ifdef _WIN32
lua_settop(L, 1);
if (path[0] == 0 || strchr("\\/", path[strlen(path) - 1]) != NULL)
lua_pushstring(L, "*");
else
lua_pushstring(L, "/*");
lua_concat(L, 2);
path = lua_tostring(L, -1);
LPWSTR wpath = utfconv_utf8towc(path);
if (wpath == NULL) {
lua_pushnil(L);
lua_pushstring(L, UTFCONV_ERROR_INVALID_CONVERSION);
return 2;
}
WIN32_FIND_DATAW fd;
HANDLE find_handle = FindFirstFileExW(wpath, FindExInfoBasic, &fd, FindExSearchNameMatch, NULL, 0);
free(wpath);
if (find_handle == INVALID_HANDLE_VALUE) {
lua_pushnil(L);
push_win32_error(L, GetLastError());
return 2;
}
char mbpath[MAX_PATH * 4]; // utf-8 spans 4 bytes at most
int len, i = 1;
lua_newtable(L);
do
{
if (wcscmp(fd.cFileName, L".") == 0) { continue; }
if (wcscmp(fd.cFileName, L"..") == 0) { continue; }
len = WideCharToMultiByte(CP_UTF8, 0, fd.cFileName, -1, mbpath, MAX_PATH * 4, NULL, NULL);
if (len == 0) { break; }
lua_pushlstring(L, mbpath, len - 1); // len includes \0
lua_rawseti(L, -2, i++);
} while (FindNextFileW(find_handle, &fd));
if (GetLastError() != ERROR_NO_MORE_FILES) {
lua_pushnil(L);
push_win32_error(L, GetLastError());
FindClose(find_handle);
return 2;
}
FindClose(find_handle);
return 1;
#else
DIR *dir = opendir(path);
if (!dir) { if (!dir) {
lua_pushnil(L); lua_pushnil(L);
lua_pushstring(L, strerror(errno)); lua_pushstring(L, SDL_GetError());
return 2; return 2;
} }
lua_newtable(L); lua_createtable(L, count, 0);
int i = 1; for (int ti = 1, i = 0; i < count; i++) {
struct dirent *entry; if (strcmp(dir[i], ".") == 0) continue;
while ( (entry = readdir(dir)) ) { if (strcmp(dir[i], "..") == 0) continue;
if (strcmp(entry->d_name, "." ) == 0) { continue; } lua_pushstring(L, dir[i]);
if (strcmp(entry->d_name, "..") == 0) { continue; } lua_rawseti(L, -2, ti++);
lua_pushstring(L, entry->d_name);
lua_rawseti(L, -2, i);
i++;
} }
SDL_free(dir);
closedir(dir);
return 1; return 1;
#endif
} }
+23 -40
View File
@@ -1,6 +1,7 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <SDL.h> #include <SDL3/SDL.h>
#include <SDL3/SDL_main.h>
#include "api/api.h" #include "api/api.h"
#include "rencache.h" #include "rencache.h"
#include "renderer.h" #include "renderer.h"
@@ -11,7 +12,7 @@
#include <windows.h> #include <windows.h>
#elif defined(__linux__) #elif defined(__linux__)
#include <unistd.h> #include <unistd.h>
#elif defined(__APPLE__) #elif defined(SDL_PLATFORM_APPLE)
#include <mach-o/dyld.h> #include <mach-o/dyld.h>
#elif defined(__FreeBSD__) #elif defined(__FreeBSD__)
#include <sys/sysctl.h> #include <sys/sysctl.h>
@@ -39,7 +40,7 @@ static void get_exe_filename(char *buf, int sz) {
ssize_t len = readlink(path, buf, sz - 1); ssize_t len = readlink(path, buf, sz - 1);
if (len > 0) if (len > 0)
buf[len] = '\0'; buf[len] = '\0';
#elif __APPLE__ #elif SDL_PLATFORM_APPLE
/* use realpath to resolve a symlink if the process was launched from one. /* use realpath to resolve a symlink if the process was launched from one.
** This happens when Homebrew installs a cack and creates a symlink in ** This happens when Homebrew installs a cack and creates a symlink in
** /usr/loca/bin for launching the executable from the command line. */ ** /usr/loca/bin for launching the executable from the command line. */
@@ -61,15 +62,10 @@ static void init_window_icon(void) {
#if !defined(_WIN32) && !defined(__APPLE__) #if !defined(_WIN32) && !defined(__APPLE__)
#include "../resources/icons/icon.inl" #include "../resources/icons/icon.inl"
(void) icon_rgba_len; /* unused */ (void) icon_rgba_len; /* unused */
SDL_Surface *surf = SDL_CreateRGBSurfaceFrom( SDL_PixelFormat format = SDL_GetPixelFormatForMasks(32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000);
icon_rgba, 64, 64, SDL_Surface *surf = SDL_CreateSurfaceFrom(64, 64, format, icon_rgba, 64 * 4);
32, 64 * 4,
0x000000ff,
0x0000ff00,
0x00ff0000,
0xff000000);
SDL_SetWindowIcon(window, surf); SDL_SetWindowIcon(window, surf);
SDL_FreeSurface(surf); SDL_DestroySurface(surf);
#endif #endif
} }
@@ -83,7 +79,7 @@ static void init_window_icon(void) {
#define LITE_NONPATHSEP_PATTERN "[^/]+" #define LITE_NONPATHSEP_PATTERN "[^/]+"
#endif #endif
#ifdef __APPLE__ #ifdef SDL_PLATFORM_APPLE
void enable_momentum_scroll(); void enable_momentum_scroll();
#ifdef MACOS_USE_BUNDLE #ifdef MACOS_USE_BUNDLE
void set_macos_bundle_resources(lua_State *L); void set_macos_bundle_resources(lua_State *L);
@@ -108,7 +104,7 @@ void set_macos_bundle_resources(lua_State *L);
#define ARCH_PLATFORM "linux" #define ARCH_PLATFORM "linux"
#elif __FreeBSD__ #elif __FreeBSD__
#define ARCH_PLATFORM "freebsd" #define ARCH_PLATFORM "freebsd"
#elif __APPLE__ #elif SDL_PLATFORM_APPLE
#define ARCH_PLATFORM "darwin" #define ARCH_PLATFORM "darwin"
#endif #endif
@@ -124,53 +120,38 @@ int main(int argc, char **argv) {
signal(SIGPIPE, SIG_IGN); signal(SIGPIPE, SIG_IGN);
#endif #endif
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS) != 0) { if (!SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS)) {
fprintf(stderr, "Error initializing SDL: %s\n", SDL_GetError()); fprintf(stderr, "Error initializing SDL: %s", SDL_GetError());
exit(1); exit(1);
} }
SDL_EnableScreenSaver(); SDL_EnableScreenSaver();
SDL_EventState(SDL_DROPFILE, SDL_ENABLE); SDL_SetEventEnabled(SDL_EVENT_DROP_FILE, true);
atexit(SDL_Quit); atexit(SDL_Quit);
#ifdef SDL_HINT_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR /* Available since 2.0.8 */
SDL_SetHint(SDL_HINT_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR, "0"); SDL_SetHint(SDL_HINT_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR, "0");
#endif
#if SDL_VERSION_ATLEAST(2, 0, 5)
SDL_SetHint(SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH, "1"); SDL_SetHint(SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH, "1");
#endif SDL_SetHint(SDL_HINT_IME_IMPLEMENTED_UI, "1");
#if SDL_VERSION_ATLEAST(2, 0, 18) SDL_SetHint(SDL_HINT_RENDER_DRIVER, "software");
SDL_SetHint(SDL_HINT_IME_SHOW_UI, "1");
#endif
#if SDL_VERSION_ATLEAST(2, 0, 22)
SDL_SetHint(SDL_HINT_IME_SUPPORT_EXTENDED_TEXT, "1");
#endif
#if SDL_VERSION_ATLEAST(2, 0, 8)
/* This hint tells SDL to respect borderless window as a normal window. /* This hint tells SDL to respect borderless window as a normal window.
** For example, the window will sit right on top of the taskbar instead ** For example, the window will sit right on top of the taskbar instead
** of obscuring it. */ ** of obscuring it. */
SDL_SetHint("SDL_BORDERLESS_WINDOWED_STYLE", "1"); SDL_SetHint("SDL_BORDERLESS_WINDOWED_STYLE", "1");
#endif
#if SDL_VERSION_ATLEAST(2, 0, 12)
/* This hint tells SDL to allow the user to resize a borderless windoow. /* This hint tells SDL to allow the user to resize a borderless windoow.
** It also enables aero-snap on Windows apparently. */ ** It also enables aero-snap on Windows apparently. */
SDL_SetHint("SDL_BORDERLESS_RESIZABLE_STYLE", "1"); SDL_SetHint("SDL_BORDERLESS_RESIZABLE_STYLE", "1");
#endif SDL_SetHint(SDL_HINT_MOUSE_DOUBLE_CLICK_RADIUS, "4");
#if SDL_VERSION_ATLEAST(2, 0, 9)
SDL_SetHint("SDL_MOUSE_DOUBLE_CLICK_RADIUS", "4");
#endif
SDL_DisplayMode dm;
SDL_GetCurrentDisplayMode(0, &dm);
const SDL_DisplayMode* dm = SDL_GetCurrentDisplayMode(SDL_GetPrimaryDisplay());
window = SDL_CreateWindow( window = SDL_CreateWindow(
"", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, dm.w * 0.8, dm.h * 0.8, "", (dm ? dm->w : 2) * 0.8, (dm ? dm->h : 2) * 0.8,
SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI | SDL_WINDOW_HIDDEN); SDL_WINDOW_RESIZABLE | SDL_WINDOW_HIGH_PIXEL_DENSITY | SDL_WINDOW_HIDDEN);
init_window_icon();
if (!window) { if (!window) {
fprintf(stderr, "Error creating lite-xl window: %s", SDL_GetError()); fprintf(stderr, "Error creating lite-xl window: %s", SDL_GetError());
exit(1); exit(1);
} }
init_window_icon();
if (ren_init(window) != 0) { if (ren_init(window) != 0) {
fprintf(stderr, "Error initializing renderer: %s\n", SDL_GetError()); fprintf(stderr, "Error initializing renderer: %s\n", SDL_GetError());
exit(1); exit(1);
@@ -206,12 +187,14 @@ init_lua:
} }
lua_setglobal(L, "EXEFILE"); lua_setglobal(L, "EXEFILE");
#ifdef __APPLE__ #ifdef SDL_PLATFORM_APPLE
enable_momentum_scroll(); enable_momentum_scroll();
#ifdef MACOS_USE_BUNDLE #ifdef MACOS_USE_BUNDLE
set_macos_bundle_resources(L); set_macos_bundle_resources(L);
#endif #endif
#endif #endif
SDL_SetEventEnabled(SDL_EVENT_TEXT_INPUT, true);
SDL_SetEventEnabled(SDL_EVENT_TEXT_EDITING, true);
const char *init_lite_code = \ const char *init_lite_code = \
"local core\n" "local core\n"
+2 -60
View File
@@ -59,67 +59,9 @@ freetype_dep = dependency('freetype2', fallback: ['freetype2', 'freetype_dep'],
) )
sdl_options = ['default_library=static'] sdl_dep = dependency('sdl3', static: true)
# we explicitly need these lite_deps = [lua_dep, sdl_dep, freetype_dep, pcre2_dep, libm, libdl]
sdl_options += 'use_loadso=enabled'
sdl_options += 'prefer_dlopen=true'
sdl_options += 'use_video=enabled'
sdl_options += 'use_atomic=enabled'
sdl_options += 'use_threads=enabled'
sdl_options += 'use_timers=enabled'
# investigate if this is truly needed
# Do not remove before https://github.com/libsdl-org/SDL/issues/5413 is released
sdl_options += 'use_events=enabled'
if host_machine.system() == 'darwin' or host_machine.system() == 'windows'
sdl_options += 'use_video_x11=disabled'
sdl_options += 'use_video_wayland=disabled'
else
sdl_options += 'use_render=enabled'
sdl_options += 'use_video_x11=auto'
sdl_options += 'use_video_wayland=auto'
endif
# we leave this up to what the host system has except on windows
if host_machine.system() != 'windows'
sdl_options += 'use_video_opengl=auto'
sdl_options += 'use_video_openglesv2=auto'
else
sdl_options += 'use_video_opengl=disabled'
sdl_options += 'use_video_openglesv2=disabled'
endif
# we don't need these
sdl_options += 'test=false'
sdl_options += 'use_sensor=disabled'
sdl_options += 'use_haptic=disabled'
sdl_options += 'use_hidapi=disabled'
sdl_options += 'use_audio=disabled'
sdl_options += 'use_cpuinfo=disabled'
sdl_options += 'use_joystick=disabled'
sdl_options += 'use_joystick_xinput=disabled'
sdl_options += 'use_video_vulkan=disabled'
sdl_options += 'use_video_offscreen=disabled'
sdl_options += 'use_power=disabled'
sdl_options += 'system_iconv=disabled'
sdl_dep = dependency('sdl2', fallback: ['sdl2', 'sdl2_dep'],
default_options: default_fallback_options + sdl_options
)
if host_machine.system() == 'windows'
if sdl_dep.type_name() == 'internal'
sdlmain_dep = dependency('sdl2main', fallback: ['sdl2main_dep'])
else
sdlmain_dep = cc.find_library('SDL2main')
endif
else
sdlmain_dep = dependency('', required: false)
assert(not sdlmain_dep.found(), 'checking if fake dependency has been found')
endif
lite_deps = [lua_dep, sdl_dep, sdlmain_dep, freetype_dep, pcre2_dep, libm, libdl]
lite_sources += 'api/dirmonitor.c' lite_sources += 'api/dirmonitor.c'
# dirmonitor backend # dirmonitor backend
+1
View File
@@ -1,3 +1,4 @@
#include <stdlib.h>
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
#include <stdio.h> #include <stdio.h>
+46 -35
View File
@@ -214,7 +214,7 @@ static unsigned int font_get_glyph_id(RenFont *font, unsigned int codepoint) {
#define FONT_BITMAP_COUNT(F) ((F)->antialiasing == FONT_ANTIALIASING_SUBPIXEL ? SUBPIXEL_BITMAPS_CACHED : 1) #define FONT_BITMAP_COUNT(F) ((F)->antialiasing == FONT_ANTIALIASING_SUBPIXEL ? SUBPIXEL_BITMAPS_CACHED : 1)
#define SLOT_BITMAP_TYPE(B) ((B).pixel_mode == FT_PIXEL_MODE_LCD ? EGlyphFormatSubpixel : EGlyphFormatGrayscale) #define SLOT_BITMAP_TYPE(B) ((B).pixel_mode == FT_PIXEL_MODE_LCD ? EGlyphFormatSubpixel : EGlyphFormatGrayscale)
static inline SDL_PixelFormatEnum glyphformat_to_pixelformat(ERenGlyphFormat format, int *depth) { static inline SDL_PixelFormat glyphformat_to_pixelformat(ERenGlyphFormat format, int *depth) {
switch (format) { switch (format) {
case EGlyphFormatSubpixel: *depth = 24; return SDL_PIXELFORMAT_RGB24; case EGlyphFormatSubpixel: *depth = 24; return SDL_PIXELFORMAT_RGB24;
case EGlyphFormatGrayscale: *depth = 8; return SDL_PIXELFORMAT_INDEX8; case EGlyphFormatGrayscale: *depth = 8; return SDL_PIXELFORMAT_INDEX8;
@@ -245,12 +245,14 @@ static SDL_Surface *font_allocate_glyph_surface(RenFont *font, FT_GlyphSlot slot
} }
metric->atlas_idx = atlas_idx; metric->atlas_idx = atlas_idx;
GlyphAtlas *atlas = &font->glyphs.atlas[glyph_format][atlas_idx]; GlyphAtlas *atlas = &font->glyphs.atlas[glyph_format][atlas_idx];
SDL_PropertiesID userdata;
// find the surface with the minimum height that can fit the glyph (limited to last 100 surfaces) // find the surface with the minimum height that can fit the glyph (limited to last 100 surfaces)
int surface_idx = -1, max_surface_idx = (int) atlas->nsurface - 100, min_waste = INT_MAX; int surface_idx = -1, max_surface_idx = (int) atlas->nsurface - 100, min_waste = INT_MAX;
for (int i = atlas->nsurface - 1; i >= 0 && i > max_surface_idx; i--) { for (int i = atlas->nsurface - 1; i >= 0 && i > max_surface_idx; i--) {
assert(atlas->surfaces[i]->userdata); userdata = SDL_GetSurfaceProperties(atlas->surfaces[i]);
GlyphMetric *m = (GlyphMetric *) atlas->surfaces[i]->userdata; assert(SDL_HasProperty(userdata, "metric"));
GlyphMetric *m = (GlyphMetric *) SDL_GetPointerProperty(userdata, "metric", NULL);
int new_min_waste = (int) atlas->surfaces[i]->h - (int) m->y1; int new_min_waste = (int) atlas->surfaces[i]->h - (int) m->y1;
if (new_min_waste >= metric->y1 && new_min_waste < min_waste) { if (new_min_waste >= metric->y1 && new_min_waste < min_waste) {
surface_idx = i; surface_idx = i;
@@ -262,19 +264,22 @@ static SDL_Surface *font_allocate_glyph_surface(RenFont *font, FT_GlyphSlot slot
int h = FONT_HEIGHT_OVERFLOW_PX + (double) font->face->size->metrics.height / 64.0f; int h = FONT_HEIGHT_OVERFLOW_PX + (double) font->face->size->metrics.height / 64.0f;
if (h <= FONT_HEIGHT_OVERFLOW_PX) h += slot->bitmap.rows; if (h <= FONT_HEIGHT_OVERFLOW_PX) h += slot->bitmap.rows;
if (h <= FONT_HEIGHT_OVERFLOW_PX) h += font->size; if (h <= FONT_HEIGHT_OVERFLOW_PX) h += font->size;
int depth = 0; SDL_PixelFormatEnum format = glyphformat_to_pixelformat(glyph_format, &depth); int depth = 0;
SDL_PixelFormat format = glyphformat_to_pixelformat(glyph_format, &depth);
atlas->surfaces = check_alloc(realloc(atlas->surfaces, sizeof(SDL_Surface *) * (atlas->nsurface + 1))); atlas->surfaces = check_alloc(realloc(atlas->surfaces, sizeof(SDL_Surface *) * (atlas->nsurface + 1)));
atlas->surfaces[atlas->nsurface] = check_alloc(SDL_CreateRGBSurfaceWithFormat(0, atlas->width, GLYPHS_PER_ATLAS * h, depth, format)); atlas->surfaces[atlas->nsurface] = check_alloc(SDL_CreateSurface(atlas->width, GLYPHS_PER_ATLAS * h, format));
atlas->surfaces[atlas->nsurface]->userdata = NULL; userdata = SDL_GetSurfaceProperties(atlas->surfaces[atlas->nsurface]);
SDL_SetPointerProperty(userdata, "metric", NULL);
surface_idx = atlas->nsurface++; surface_idx = atlas->nsurface++;
font->glyphs.bytesize += (sizeof(SDL_Surface *) + sizeof(SDL_Surface) + atlas->width * GLYPHS_PER_ATLAS * h * glyph_format); font->glyphs.bytesize += (sizeof(SDL_Surface *) + sizeof(SDL_Surface) + atlas->width * GLYPHS_PER_ATLAS * h * glyph_format);
} }
metric->surface_idx = surface_idx; metric->surface_idx = surface_idx;
if (atlas->surfaces[surface_idx]->userdata) { userdata = SDL_GetSurfaceProperties(atlas->surfaces[surface_idx]);
GlyphMetric *last_metric = (GlyphMetric *) atlas->surfaces[surface_idx]->userdata; if (SDL_HasProperty(userdata, "metric")) {
GlyphMetric *last_metric = (GlyphMetric *) SDL_GetPointerProperty(userdata, "metric", NULL);
metric->y0 = last_metric->y1; metric->y1 += last_metric->y1; metric->y0 = last_metric->y1; metric->y1 += last_metric->y1;
} }
atlas->surfaces[surface_idx]->userdata = (void *) metric; SDL_SetPointerProperty(userdata, "metric", (void *) metric);
return atlas->surfaces[surface_idx]; return atlas->surfaces[surface_idx];
} }
@@ -387,7 +392,7 @@ static void font_clear_glyph_cache(RenFont* font) {
for (int atlas_idx = 0; atlas_idx < font->glyphs.natlas[glyph_format_idx]; atlas_idx++) { for (int atlas_idx = 0; atlas_idx < font->glyphs.natlas[glyph_format_idx]; atlas_idx++) {
GlyphAtlas *atlas = &font->glyphs.atlas[glyph_format_idx][atlas_idx]; GlyphAtlas *atlas = &font->glyphs.atlas[glyph_format_idx][atlas_idx];
for (int surface_idx = 0; surface_idx < atlas->nsurface; surface_idx++) { for (int surface_idx = 0; surface_idx < atlas->nsurface; surface_idx++) {
SDL_FreeSurface(atlas->surfaces[surface_idx]); SDL_DestroySurface(atlas->surfaces[surface_idx]);
} }
free(atlas->surfaces); free(atlas->surfaces);
} }
@@ -408,11 +413,11 @@ static void font_clear_glyph_cache(RenFont* font) {
// based on https://github.com/libsdl-org/SDL_ttf/blob/2a094959055fba09f7deed6e1ffeb986188982ae/SDL_ttf.c#L1735 // based on https://github.com/libsdl-org/SDL_ttf/blob/2a094959055fba09f7deed6e1ffeb986188982ae/SDL_ttf.c#L1735
static unsigned long font_file_read(FT_Stream stream, unsigned long offset, unsigned char *buffer, unsigned long count) { static unsigned long font_file_read(FT_Stream stream, unsigned long offset, unsigned char *buffer, unsigned long count) {
uint64_t amount; uint64_t amount;
SDL_RWops *file = (SDL_RWops *) stream->descriptor.pointer; SDL_IOStream *file = (SDL_IOStream *) stream->descriptor.pointer;
SDL_RWseek(file, (int) offset, RW_SEEK_SET); SDL_SeekIO(file, (int) offset, SDL_IO_SEEK_SET);
if (count == 0) if (count == 0)
return 0; return 0;
amount = SDL_RWread(file, buffer, sizeof(char), count); amount = SDL_ReadIO(file, buffer, sizeof(char) * count);
if (amount <= 0) if (amount <= 0)
return 0; return 0;
return (unsigned long) amount; return (unsigned long) amount;
@@ -420,7 +425,7 @@ static unsigned long font_file_read(FT_Stream stream, unsigned long offset, unsi
static void font_file_close(FT_Stream stream) { static void font_file_close(FT_Stream stream) {
if (stream && stream->descriptor.pointer) if (stream && stream->descriptor.pointer)
SDL_RWclose((SDL_RWops *) stream->descriptor.pointer); SDL_CloseIO((SDL_IOStream *) stream->descriptor.pointer);
free(stream); free(stream);
} }
@@ -453,13 +458,11 @@ static int font_set_face_metrics(RenFont *font, FT_Face face) {
RenFont* ren_font_load(RenWindow *window_renderer, const char* path, float size, ERenFontAntialiasing antialiasing, ERenFontHinting hinting, unsigned char style) { RenFont* ren_font_load(RenWindow *window_renderer, const char* path, float size, ERenFontAntialiasing antialiasing, ERenFontHinting hinting, unsigned char style) {
FT_Error err = FT_Err_Ok; FT_Error err = FT_Err_Ok;
SDL_RWops *file = NULL; RenFont *font = NULL; SDL_IOStream *file = NULL; RenFont *font = NULL;
FT_Face face = NULL; FT_Stream stream = NULL; FT_Face face = NULL; FT_Stream stream = NULL;
SDL_ClearError(); file = SDL_IOFromFile(path, "rb");
if (!file) return NULL; // error set by SDL_IOFromFile
file = SDL_RWFromFile(path, "rb");
if (!file) return NULL; // error set by SDL_RWFromFile
int len = strlen(path); int len = strlen(path);
font = check_alloc(calloc(1, sizeof(RenFont) + len + 1)); font = check_alloc(calloc(1, sizeof(RenFont) + len + 1));
@@ -479,7 +482,7 @@ RenFont* ren_font_load(RenWindow *window_renderer, const char* path, float size,
stream->close = &font_file_close; stream->close = &font_file_close;
stream->descriptor.pointer = file; stream->descriptor.pointer = file;
stream->pos = 0; stream->pos = 0;
stream->size = (unsigned long) SDL_RWsize(file); stream->size = (unsigned long) SDL_GetIOSize(file);
if ((err = FT_Open_Face(library, &(FT_Open_Args) { .flags = FT_OPEN_STREAM, .stream = stream }, 0, &face)) != 0) if ((err = FT_Open_Face(library, &(FT_Open_Args) { .flags = FT_OPEN_STREAM, .stream = stream }, 0, &face)) != 0)
goto failure; goto failure;
@@ -488,7 +491,7 @@ RenFont* ren_font_load(RenWindow *window_renderer, const char* path, float size,
return font; return font;
stream_failure: stream_failure:
if (file) SDL_RWclose(file); if (file) SDL_CloseIO(file);
failure: failure:
if (err != FT_Err_Ok) SDL_SetError("%s", get_ft_error(err)); if (err != FT_Err_Ok) SDL_SetError("%s", get_ft_error(err));
if (face) FT_Done_Face(face); if (face) FT_Done_Face(face);
@@ -596,7 +599,7 @@ void ren_font_dump(RenFont *font) {
double ren_draw_text(RenSurface *rs, RenFont **fonts, const char *text, size_t len, float x, int y, RenColor color) { double ren_draw_text(RenSurface *rs, RenFont **fonts, const char *text, size_t len, float x, int y, RenColor color) {
SDL_Surface *surface = rs->surface; SDL_Surface *surface = rs->surface;
SDL_Rect clip; SDL_Rect clip;
SDL_GetClipRect(surface, &clip); SDL_GetSurfaceClipRect(surface, &clip);
const int surface_scale = rs->scale; const int surface_scale = rs->scale;
double pen_x = x * surface_scale; double pen_x = x * surface_scale;
@@ -637,12 +640,20 @@ double ren_draw_text(RenSurface *rs, RenFont **fonts, const char *text, size_t l
start_x += offset; start_x += offset;
glyph_start += offset; glyph_start += offset;
} }
uint32_t* destination_pixel = (uint32_t*)&(destination_pixels[surface->pitch * target_y + start_x * surface->format->BytesPerPixel ]);
uint8_t* source_pixel = &source_pixels[line * font_surface->pitch + glyph_start * font_surface->format->BytesPerPixel]; const SDL_PixelFormatDetails* surface_format = SDL_GetPixelFormatDetails(surface->format);
const SDL_PixelFormatDetails* font_surface_format = SDL_GetPixelFormatDetails(font_surface->format);
uint32_t* destination_pixel = (uint32_t*)&(destination_pixels[surface->pitch * target_y + start_x * surface_format->bytes_per_pixel]);
uint8_t* source_pixel = &source_pixels[line * font_surface->pitch + glyph_start * font_surface_format->bytes_per_pixel];
for (int x = glyph_start; x < glyph_end; ++x) { for (int x = glyph_start; x < glyph_end; ++x) {
uint32_t destination_color = *destination_pixel; uint32_t destination_color = *destination_pixel;
// the standard way of doing this would be SDL_GetRGBA, but that introduces a performance regression. needs to be investigated // the standard way of doing this would be SDL_GetRGBA, but that introduces a performance regression. needs to be investigated
SDL_Color dst = { (destination_color & surface->format->Rmask) >> surface->format->Rshift, (destination_color & surface->format->Gmask) >> surface->format->Gshift, (destination_color & surface->format->Bmask) >> surface->format->Bshift, (destination_color & surface->format->Amask) >> surface->format->Ashift }; SDL_Color dst = {
(destination_color & surface_format->Rmask) >> surface_format->Rshift,
(destination_color & surface_format->Gmask) >> surface_format->Gshift,
(destination_color & surface_format->Bmask) >> surface_format->Bshift,
(destination_color & surface_format->Amask) >> surface_format->Ashift};
SDL_Color src; SDL_Color src;
if (metric->format == EGlyphFormatSubpixel) { if (metric->format == EGlyphFormatSubpixel) {
@@ -660,7 +671,7 @@ double ren_draw_text(RenSurface *rs, RenFont **fonts, const char *text, size_t l
g = (color.g * src.g * color.a + dst.g * (65025 - src.g * color.a) + 32767) / 65025; g = (color.g * src.g * color.a + dst.g * (65025 - src.g * color.a) + 32767) / 65025;
b = (color.b * src.b * color.a + dst.b * (65025 - src.b * color.a) + 32767) / 65025; b = (color.b * src.b * color.a + dst.b * (65025 - src.b * color.a) + 32767) / 65025;
// the standard way of doing this would be SDL_GetRGBA, but that introduces a performance regression. needs to be investigated // the standard way of doing this would be SDL_GetRGBA, but that introduces a performance regression. needs to be investigated
*destination_pixel++ = (unsigned int) dst.a << surface->format->Ashift | r << surface->format->Rshift | g << surface->format->Gshift | b << surface->format->Bshift; *destination_pixel++ = (unsigned int) dst.a << surface_format->Ashift | r << surface_format->Rshift | g << surface_format->Gshift | b << surface_format->Bshift;
} }
} }
} }
@@ -704,25 +715,25 @@ void ren_draw_rect(RenSurface *rs, RenRect rect, RenColor color) {
rect.height * surface_scale }; rect.height * surface_scale };
if (color.a == 0xff) { if (color.a == 0xff) {
uint32_t translated = SDL_MapRGB(surface->format, color.r, color.g, color.b); uint32_t translated = SDL_MapSurfaceRGB(surface, color.r, color.g, color.b);
SDL_FillRect(surface, &dest_rect, translated); SDL_FillSurfaceRect(surface, &dest_rect, translated);
} else { } else {
// Seems like SDL doesn't handle clipping as we expect when using // Seems like SDL doesn't handle clipping as we expect when using
// scaled blitting, so we "clip" manually. // scaled blitting, so we "clip" manually.
SDL_Rect clip; SDL_Rect clip;
SDL_GetClipRect(surface, &clip); SDL_GetSurfaceClipRect(surface, &clip);
if (!SDL_IntersectRect(&clip, &dest_rect, &dest_rect)) return; if (!SDL_GetRectIntersection(&clip, &dest_rect, &dest_rect)) return;
uint32_t *pixel = (uint32_t *)draw_rect_surface->pixels; uint32_t *pixel = (uint32_t *)draw_rect_surface->pixels;
*pixel = SDL_MapRGBA(draw_rect_surface->format, color.r, color.g, color.b, color.a); *pixel = SDL_MapSurfaceRGBA(draw_rect_surface, color.r, color.g, color.b, color.a);
SDL_BlitScaled(draw_rect_surface, NULL, surface, &dest_rect); SDL_BlitSurfaceScaled(draw_rect_surface, NULL, surface, &dest_rect, SDL_SCALEMODE_LINEAR);
} }
} }
/*************** Window Management ****************/ /*************** Window Management ****************/
void ren_free_window_resources(RenWindow *window_renderer) { void ren_free_window_resources(RenWindow *window_renderer) {
renwin_free(window_renderer); renwin_free(window_renderer);
SDL_FreeSurface(draw_rect_surface); SDL_DestroySurface(draw_rect_surface);
free(window_renderer->command_buf); free(window_renderer->command_buf);
window_renderer->command_buf = NULL; window_renderer->command_buf = NULL;
window_renderer->command_buf_size = 0; window_renderer->command_buf_size = 0;
@@ -734,8 +745,8 @@ int ren_init(SDL_Window *win) {
SDL_ClearError(); SDL_ClearError();
assert(win); assert(win);
draw_rect_surface = SDL_CreateRGBSurface(0, 1, 1, 32, draw_rect_surface = SDL_CreateSurface(1, 1, SDL_PIXELFORMAT_RGBA32);
0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF);
if (!draw_rect_surface) if (!draw_rect_surface)
return -1; // error set by SDL_CreateRGBSurface return -1; // error set by SDL_CreateRGBSurface
+1 -1
View File
@@ -1,7 +1,7 @@
#ifndef RENDERER_H #ifndef RENDERER_H
#define RENDERER_H #define RENDERER_H
#include <SDL.h> #include <SDL3/SDL.h>
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
+16 -14
View File
@@ -1,3 +1,4 @@
#include <stdlib.h>
#include <assert.h> #include <assert.h>
#include <stdio.h> #include <stdio.h>
#include "renwindow.h" #include "renwindow.h"
@@ -6,7 +7,7 @@
static int query_surface_scale(RenWindow *ren) { static int query_surface_scale(RenWindow *ren) {
int w_pixels, h_pixels; int w_pixels, h_pixels;
int w_points, h_points; int w_points, h_points;
SDL_GL_GetDrawableSize(ren->window, &w_pixels, &h_pixels); SDL_GetWindowSizeInPixels(ren->window, &w_pixels, &h_pixels);
SDL_GetWindowSize(ren->window, &w_points, &h_points); SDL_GetWindowSize(ren->window, &w_points, &h_points);
/* We consider that the ratio pixel/point will always be an integer and /* We consider that the ratio pixel/point will always be an integer and
it is the same along the x and the y axis. */ it is the same along the x and the y axis. */
@@ -16,14 +17,14 @@ static int query_surface_scale(RenWindow *ren) {
static void setup_renderer(RenWindow *ren, int w, int h) { static void setup_renderer(RenWindow *ren, int w, int h) {
/* Note that w and h here should always be in pixels and obtained from /* Note that w and h here should always be in pixels and obtained from
a call to SDL_GL_GetDrawableSize(). */ a call to SDL_GetWindowSizeInPixels(). */
if (!ren->renderer) { if (!ren->renderer) {
ren->renderer = SDL_CreateRenderer(ren->window, -1, 0); ren->renderer = SDL_CreateRenderer(ren->window, NULL);
} }
if (ren->texture) { if (ren->texture) {
SDL_DestroyTexture(ren->texture); SDL_DestroyTexture(ren->texture);
} }
ren->texture = SDL_CreateTexture(ren->renderer, SDL_PIXELFORMAT_BGRA32, SDL_TEXTUREACCESS_STREAMING, w, h); ren->texture = SDL_CreateTexture(ren->renderer, ren->rensurface.surface->format, SDL_TEXTUREACCESS_STREAMING, w, h);
ren->rensurface.scale = query_surface_scale(ren); ren->rensurface.scale = query_surface_scale(ren);
} }
#endif #endif
@@ -33,11 +34,12 @@ void renwin_init_surface(RenWindow *ren) {
ren->scale_x = ren->scale_y = 1; ren->scale_x = ren->scale_y = 1;
#ifdef LITE_USE_SDL_RENDERER #ifdef LITE_USE_SDL_RENDERER
if (ren->rensurface.surface) { if (ren->rensurface.surface) {
SDL_FreeSurface(ren->rensurface.surface); SDL_DestroySurface(ren->rensurface.surface);
} }
int w, h; int w, h;
SDL_GL_GetDrawableSize(ren->window, &w, &h); SDL_GetWindowSizeInPixels(ren->window, &w, &h);
ren->rensurface.surface = SDL_CreateRGBSurfaceWithFormat(0, w, h, 32, SDL_PIXELFORMAT_BGRA32); SDL_PixelFormat format = SDL_GetWindowPixelFormat(ren->window);
ren->rensurface.surface = SDL_CreateSurface(w, h, format == SDL_PIXELFORMAT_UNKNOWN ? SDL_PIXELFORMAT_BGRA32 : format);
if (!ren->rensurface.surface) { if (!ren->rensurface.surface) {
fprintf(stderr, "Error creating surface: %s", SDL_GetError()); fprintf(stderr, "Error creating surface: %s", SDL_GetError());
exit(1); exit(1);
@@ -59,14 +61,14 @@ static RenRect scaled_rect(const RenRect rect, const int scale) {
void renwin_clip_to_surface(RenWindow *ren) { void renwin_clip_to_surface(RenWindow *ren) {
SDL_SetClipRect(renwin_get_surface(ren).surface, NULL); SDL_SetSurfaceClipRect(renwin_get_surface(ren).surface, NULL);
} }
void renwin_set_clip_rect(RenWindow *ren, RenRect rect) { void renwin_set_clip_rect(RenWindow *ren, RenRect rect) {
RenSurface rs = renwin_get_surface(ren); RenSurface rs = renwin_get_surface(ren);
RenRect sr = scaled_rect(rect, rs.scale); RenRect sr = scaled_rect(rect, rs.scale);
SDL_SetClipRect(rs.surface, &(SDL_Rect){.x = sr.x, .y = sr.y, .w = sr.width, .h = sr.height}); SDL_SetSurfaceClipRect(rs.surface, &(SDL_Rect){.x = sr.x, .y = sr.y, .w = sr.width, .h = sr.height});
} }
@@ -86,7 +88,7 @@ RenSurface renwin_get_surface(RenWindow *ren) {
void renwin_resize_surface(RenWindow *ren) { void renwin_resize_surface(RenWindow *ren) {
#ifdef LITE_USE_SDL_RENDERER #ifdef LITE_USE_SDL_RENDERER
int new_w, new_h, new_scale; int new_w, new_h, new_scale;
SDL_GL_GetDrawableSize(ren->window, &new_w, &new_h); SDL_GetWindowSizeInPixels(ren->window, &new_w, &new_h);
new_scale = query_surface_scale(ren); new_scale = query_surface_scale(ren);
/* Note that (w, h) may differ from (new_w, new_h) on retina displays. */ /* Note that (w, h) may differ from (new_w, new_h) on retina displays. */
if (new_scale != ren->rensurface.scale || if (new_scale != ren->rensurface.scale ||
@@ -121,10 +123,10 @@ void renwin_update_rects(RenWindow *ren, RenRect *rects, int count) {
const int x = scale * r->x, y = scale * r->y; const int x = scale * r->x, y = scale * r->y;
const int w = scale * r->width, h = scale * r->height; const int w = scale * r->width, h = scale * r->height;
const SDL_Rect sr = {.x = x, .y = y, .w = w, .h = h}; const SDL_Rect sr = {.x = x, .y = y, .w = w, .h = h};
int32_t *pixels = ((int32_t *) ren->rensurface.surface->pixels) + x + ren->rensurface.surface->w * y; uint8_t *pixels = ((uint8_t *) ren->rensurface.surface->pixels) + y * ren->rensurface.surface->pitch + x * SDL_BYTESPERPIXEL(ren->rensurface.surface->format);
SDL_UpdateTexture(ren->texture, &sr, pixels, ren->rensurface.surface->w * 4); SDL_UpdateTexture(ren->texture, &sr, pixels, ren->rensurface.surface->pitch);
} }
SDL_RenderCopy(ren->renderer, ren->texture, NULL, NULL); SDL_RenderTexture(ren->renderer, ren->texture, NULL, NULL);
SDL_RenderPresent(ren->renderer); SDL_RenderPresent(ren->renderer);
#else #else
SDL_UpdateWindowSurfaceRects(ren->window, (SDL_Rect*) rects, count); SDL_UpdateWindowSurfaceRects(ren->window, (SDL_Rect*) rects, count);
@@ -135,7 +137,7 @@ void renwin_free(RenWindow *ren) {
#ifdef LITE_USE_SDL_RENDERER #ifdef LITE_USE_SDL_RENDERER
SDL_DestroyTexture(ren->texture); SDL_DestroyTexture(ren->texture);
SDL_DestroyRenderer(ren->renderer); SDL_DestroyRenderer(ren->renderer);
SDL_FreeSurface(ren->rensurface.surface); SDL_DestroySurface(ren->rensurface.surface);
#endif #endif
SDL_DestroyWindow(ren->window); SDL_DestroyWindow(ren->window);
ren->window = NULL; ren->window = NULL;
+1 -1
View File
@@ -1,4 +1,4 @@
#include <SDL.h> #include <SDL3/SDL.h>
#include "renderer.h" #include "renderer.h"
struct RenWindow { struct RenWindow {
-15
View File
@@ -1,15 +0,0 @@
[wrap-file]
directory = SDL2-2.30.3
source_url = https://github.com/libsdl-org/SDL/releases/download/release-2.30.3/SDL2-2.30.3.tar.gz
source_filename = SDL2-2.30.3.tar.gz
source_hash = 820440072f8f5b50188c1dae104f2ad25984de268785be40c41a099a510f0aec
patch_filename = sdl2_2.30.3-2_patch.zip
patch_url = https://wrapdb.mesonbuild.com/v2/sdl2_2.30.3-2/get_patch
patch_hash = 2c08bde67b3896db88e01481c379322625ea6c928cdb68ead91d0e3749863bc2
source_fallback_url = https://github.com/mesonbuild/wrapdb/releases/download/sdl2_2.30.3-2/SDL2-2.30.3.tar.gz
wrapdb_version = 2.30.3-2
[provide]
sdl2 = sdl2_dep
sdl2main = sdl2main_dep
sdl2_test = sdl2_test_dep