SDL3 port (#1756)
* 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:
+41
-12
@@ -19,7 +19,8 @@ jobs:
|
||||
matrix:
|
||||
config:
|
||||
- { 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:
|
||||
CC: ${{ matrix.config.cc }}
|
||||
CXX: ${{ matrix.config.cxx }}
|
||||
@@ -35,21 +36,30 @@ jobs:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
# disabled because this will break our own Python install
|
||||
- name: Python Setup
|
||||
if: false
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: "3.11"
|
||||
|
||||
# disabled because the container has up-to-date packages
|
||||
- name: Update Packages
|
||||
if: false
|
||||
run: sudo apt-get update
|
||||
|
||||
# disabled as the dependencies are already installed
|
||||
- name: Install Dependencies
|
||||
if: false
|
||||
run: bash scripts/install-dependencies.sh --debug
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
bash --version
|
||||
bash scripts/build.sh --debug --forcefallback --portable
|
||||
uses: docker://ghcr.io/lite-xl/lite-xl-build-box-manylinux:v4
|
||||
with:
|
||||
entrypoint: /entrypoint.sh
|
||||
args: |
|
||||
bash --version
|
||||
bash scripts/build.sh --debug --forcefallback --portable
|
||||
|
||||
- name: Package
|
||||
if: ${{ matrix.config.cc == 'gcc' }}
|
||||
@@ -101,7 +111,7 @@ jobs:
|
||||
# installing md5sha1sum will eliminate a warning with arm64 and libusb
|
||||
- name: Install Dependencies
|
||||
run: |
|
||||
brew install bash md5sha1sum
|
||||
brew install bash md5sha1sum sdl3
|
||||
pip install meson ninja dmgbuild
|
||||
|
||||
- name: Build
|
||||
@@ -192,11 +202,14 @@ jobs:
|
||||
base-devel
|
||||
git
|
||||
zip
|
||||
mingw-w64-${{ matrix.config.arch }}-gcc
|
||||
mingw-w64-${{ matrix.config.arch }}-meson
|
||||
mingw-w64-${{ matrix.config.arch }}-ninja
|
||||
mingw-w64-${{ matrix.config.arch }}-ca-certificates
|
||||
mingw-w64-${{ matrix.config.arch }}-ntldd
|
||||
patch
|
||||
pacboy: >-
|
||||
gcc:p
|
||||
meson:p
|
||||
ca-certificates:p
|
||||
ninja:p
|
||||
pkg-config:p
|
||||
sdl3:p
|
||||
|
||||
- name: Set Environment Variables
|
||||
run: |
|
||||
@@ -251,7 +264,23 @@ jobs:
|
||||
python-version: "3.11"
|
||||
|
||||
- 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
|
||||
run: |
|
||||
@@ -276,7 +305,7 @@ jobs:
|
||||
- name: Package
|
||||
run: |
|
||||
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
|
||||
uses: actions/upload-artifact@v4
|
||||
|
||||
@@ -92,7 +92,7 @@ jobs:
|
||||
sudo apt-get install -y ccache
|
||||
|
||||
- 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:
|
||||
entrypoint: /entrypoint.sh
|
||||
args: |
|
||||
@@ -100,7 +100,7 @@ jobs:
|
||||
bash scripts/build.sh --debug --forcefallback --portable --release --lto
|
||||
|
||||
- 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:
|
||||
entrypoint: /entrypoint.sh
|
||||
args: |
|
||||
@@ -108,7 +108,7 @@ jobs:
|
||||
bash scripts/package.sh --version ${INSTALL_REF} --debug --addons --binary --release
|
||||
|
||||
- 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:
|
||||
entrypoint: /entrypoint.sh
|
||||
args: |
|
||||
@@ -164,7 +164,7 @@ jobs:
|
||||
|
||||
- name: Install Dependencies
|
||||
run: |
|
||||
brew install bash md5sha1sum
|
||||
brew install bash md5sha1sum sdl3
|
||||
pip install meson ninja dmgbuild
|
||||
|
||||
- name: Build
|
||||
@@ -269,11 +269,14 @@ jobs:
|
||||
git
|
||||
zip
|
||||
unzip
|
||||
mingw-w64-${{ matrix.config.arch }}-gcc
|
||||
mingw-w64-${{ matrix.config.arch }}-meson
|
||||
mingw-w64-${{ matrix.config.arch }}-ninja
|
||||
mingw-w64-${{ matrix.config.arch }}-ca-certificates
|
||||
mingw-w64-${{ matrix.config.arch }}-ntldd
|
||||
patch
|
||||
pacboy: >-
|
||||
gcc:p
|
||||
meson:p
|
||||
ca-certificates:p
|
||||
ninja:p
|
||||
pkg-config:p
|
||||
sdl3:p
|
||||
|
||||
- name: Set Environment Variables
|
||||
run: |
|
||||
|
||||
+1
-1
@@ -43,7 +43,7 @@ conf_data.set('PROJECT_ASSEMBLY_VERSION', meson.project_version() + '.0')
|
||||
cc = meson.get_compiler('c')
|
||||
|
||||
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
|
||||
if get_option('renderer') or host_machine.system() == 'darwin'
|
||||
lite_cargs += '-DLITE_USE_SDL_RENDERER'
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#include "api.h"
|
||||
#include "lua.h"
|
||||
#include <SDL.h>
|
||||
#include <SDL3/SDL.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
@@ -9,7 +9,7 @@ static unsigned int DIR_EVENT_TYPE = 0;
|
||||
|
||||
struct dirmonitor {
|
||||
SDL_Thread* thread;
|
||||
SDL_mutex* mutex;
|
||||
SDL_Mutex* mutex;
|
||||
char buffer[64512];
|
||||
volatile int length;
|
||||
struct dirmonitor_internal* internal;
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#include <SDL.h>
|
||||
#include <SDL3/SDL.h>
|
||||
#include <CoreServices/CoreServices.h>
|
||||
|
||||
struct dirmonitor_internal {
|
||||
SDL_mutex* lock;
|
||||
SDL_Mutex* lock;
|
||||
char** changes;
|
||||
size_t count;
|
||||
FSEventStreamRef stream;
|
||||
|
||||
+13
-13
@@ -4,8 +4,8 @@
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <SDL.h>
|
||||
#include <SDL_thread.h>
|
||||
#include <SDL3/SDL.h>
|
||||
#include <SDL3/SDL_thread.h>
|
||||
#include <assert.h>
|
||||
|
||||
#if _WIN32
|
||||
@@ -85,8 +85,8 @@ typedef struct process_kill_s {
|
||||
|
||||
typedef struct {
|
||||
bool stop;
|
||||
SDL_mutex *mutex;
|
||||
SDL_cond *has_work, *work_done;
|
||||
SDL_Mutex *mutex;
|
||||
SDL_Condition *has_work, *work_done;
|
||||
SDL_Thread *worker_thread;
|
||||
process_kill_t *head;
|
||||
process_kill_t *tail;
|
||||
@@ -133,8 +133,8 @@ static void kill_list_free(process_kill_list_t *list) {
|
||||
process_kill_t *node, *temp;
|
||||
SDL_WaitThread(list->worker_thread, NULL);
|
||||
SDL_DestroyMutex(list->mutex);
|
||||
SDL_DestroyCond(list->has_work);
|
||||
SDL_DestroyCond(list->work_done);
|
||||
SDL_DestroyCondition(list->has_work);
|
||||
SDL_DestroyCondition(list->work_done);
|
||||
node = list->head;
|
||||
while (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) {
|
||||
memset(list, 0, sizeof(process_kill_list_t));
|
||||
list->mutex = SDL_CreateMutex();
|
||||
list->has_work = SDL_CreateCond();
|
||||
list->work_done = SDL_CreateCond();
|
||||
list->has_work = SDL_CreateCondition();
|
||||
list->work_done = SDL_CreateCondition();
|
||||
list->head = list->tail = NULL;
|
||||
list->stop = false;
|
||||
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);
|
||||
// wait until list is empty
|
||||
while (list->head)
|
||||
SDL_CondWait(list->work_done, list->mutex);
|
||||
SDL_WaitCondition(list->work_done, list->mutex);
|
||||
// tell the worker to stop
|
||||
list->stop = true;
|
||||
SDL_CondSignal(list->has_work);
|
||||
SDL_SignalCondition(list->has_work);
|
||||
SDL_UnlockMutex(list->mutex);
|
||||
}
|
||||
|
||||
@@ -257,7 +257,7 @@ static int kill_list_worker(void *ud) {
|
||||
|
||||
// wait until we have work to do
|
||||
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;
|
||||
|
||||
@@ -279,7 +279,7 @@ static int kill_list_worker(void *ud) {
|
||||
kill_list_push(list, current_task);
|
||||
} else {
|
||||
free_task:
|
||||
SDL_CondSignal(list->work_done);
|
||||
SDL_SignalCondition(list->work_done);
|
||||
process_handle_close(¤t_task->handle);
|
||||
free(current_task);
|
||||
}
|
||||
@@ -759,7 +759,7 @@ static int f_gc(lua_State* L) {
|
||||
p->tries = 1;
|
||||
SDL_LockMutex(list->mutex);
|
||||
kill_list_push(list, p);
|
||||
SDL_CondSignal(list->has_work);
|
||||
SDL_SignalCondition(list->has_work);
|
||||
SDL_UnlockMutex(list->mutex);
|
||||
}
|
||||
}
|
||||
|
||||
+177
-241
@@ -1,4 +1,5 @@
|
||||
#include <SDL.h>
|
||||
#include <SDL3/SDL.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.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 *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?
|
||||
** 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. */
|
||||
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];
|
||||
} else {
|
||||
/* 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
|
||||
the unicode range (>0x10FFFF). Users can remap these buttons, so we need
|
||||
to return the correct name, not scancode based. */
|
||||
if ((e->key.keysym.sym < 128) || (e->key.keysym.sym & SDLK_SCANCODE_MASK))
|
||||
strcpy(buf, SDL_GetKeyName(e->key.keysym.sym));
|
||||
if ((e->key.key < 128) || (e->key.key & SDLK_SCANCODE_MASK))
|
||||
strcpy(buf, SDL_GetKeyName(e->key.key));
|
||||
else
|
||||
strcpy(buf, SDL_GetScancodeName(scancode));
|
||||
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) {
|
||||
char buf[16];
|
||||
int mx, my, w, h;
|
||||
float mx, my;
|
||||
int w, h;
|
||||
SDL_Event e;
|
||||
SDL_Event event_plus;
|
||||
|
||||
@@ -181,184 +183,205 @@ top:
|
||||
}
|
||||
|
||||
switch (e.type) {
|
||||
case SDL_QUIT:
|
||||
case SDL_EVENT_QUIT:
|
||||
lua_pushstring(L, "quit");
|
||||
return 1;
|
||||
|
||||
case SDL_WINDOWEVENT:
|
||||
if (e.window.event == SDL_WINDOWEVENT_RESIZED) {
|
||||
case SDL_EVENT_WINDOW_RESIZED:
|
||||
{
|
||||
ren_resize_window(&window_renderer);
|
||||
lua_pushstring(L, "resized");
|
||||
/* The size below will be in points. */
|
||||
lua_pushinteger(L, e.window.data1);
|
||||
lua_pushinteger(L, e.window.data2);
|
||||
return 3;
|
||||
} else if (e.window.event == SDL_WINDOWEVENT_EXPOSED) {
|
||||
rencache_invalidate();
|
||||
lua_pushstring(L, "exposed");
|
||||
return 1;
|
||||
} else if (e.window.event == SDL_WINDOWEVENT_MINIMIZED) {
|
||||
lua_pushstring(L, "minimized");
|
||||
return 1;
|
||||
} else if (e.window.event == SDL_WINDOWEVENT_MAXIMIZED) {
|
||||
lua_pushstring(L, "maximized");
|
||||
return 1;
|
||||
} else if (e.window.event == SDL_WINDOWEVENT_RESTORED) {
|
||||
lua_pushstring(L, "restored");
|
||||
return 1;
|
||||
} else if (e.window.event == SDL_WINDOWEVENT_LEAVE) {
|
||||
lua_pushstring(L, "mouseleft");
|
||||
return 1;
|
||||
}
|
||||
if (e.window.event == SDL_WINDOWEVENT_FOCUS_LOST) {
|
||||
lua_pushstring(L, "focuslost");
|
||||
return 1;
|
||||
}
|
||||
|
||||
case SDL_EVENT_WINDOW_EXPOSED:
|
||||
rencache_invalidate();
|
||||
lua_pushstring(L, "exposed");
|
||||
return 1;
|
||||
|
||||
case SDL_EVENT_WINDOW_MINIMIZED:
|
||||
lua_pushstring(L, "minimized");
|
||||
return 1;
|
||||
|
||||
case SDL_EVENT_WINDOW_MAXIMIZED:
|
||||
lua_pushstring(L, "maximized");
|
||||
return 1;
|
||||
|
||||
case SDL_EVENT_WINDOW_RESTORED:
|
||||
lua_pushstring(L, "restored");
|
||||
return 1;
|
||||
|
||||
case SDL_EVENT_WINDOW_MOUSE_LEAVE:
|
||||
lua_pushstring(L, "mouseleft");
|
||||
return 1;
|
||||
|
||||
case SDL_EVENT_WINDOW_FOCUS_LOST:
|
||||
lua_pushstring(L, "focuslost");
|
||||
return 1;
|
||||
|
||||
case SDL_EVENT_WINDOW_FOCUS_GAINED:
|
||||
/* on some systems, when alt-tabbing to the window SDL will queue up
|
||||
** several KEYDOWN events for the `tab` key; we flush all keydown
|
||||
** events on focus so these are discarded */
|
||||
if (e.window.event == SDL_WINDOWEVENT_FOCUS_GAINED) {
|
||||
SDL_FlushEvent(SDL_KEYDOWN);
|
||||
}
|
||||
SDL_FlushEvent(SDL_EVENT_KEY_DOWN);
|
||||
goto top;
|
||||
|
||||
case SDL_DROPFILE:
|
||||
SDL_GetMouseState(&mx, &my);
|
||||
lua_pushstring(L, "filedropped");
|
||||
lua_pushstring(L, e.drop.file);
|
||||
lua_pushinteger(L, mx * window_renderer.scale_x);
|
||||
lua_pushinteger(L, my * window_renderer.scale_y);
|
||||
SDL_free(e.drop.file);
|
||||
return 4;
|
||||
|
||||
case SDL_KEYDOWN:
|
||||
case SDL_EVENT_DROP_FILE:
|
||||
{
|
||||
SDL_GetMouseState(&mx, &my);
|
||||
lua_pushstring(L, "filedropped");
|
||||
lua_pushstring(L, e.drop.data);
|
||||
lua_pushinteger(L, mx * window_renderer.scale_x);
|
||||
lua_pushinteger(L, my * window_renderer.scale_y);
|
||||
return 4;
|
||||
}
|
||||
|
||||
case SDL_EVENT_KEY_DOWN:
|
||||
#ifdef __APPLE__
|
||||
/* 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
|
||||
** 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)) {
|
||||
SDL_FlushEvent(SDL_QUIT);
|
||||
if ((e.key.key == SDLK_W) && (e.key.mod & SDL_KMOD_GUI)) {
|
||||
SDL_FlushEvent(SDL_EVENT_QUIT);
|
||||
}
|
||||
#endif
|
||||
lua_pushstring(L, "keypressed");
|
||||
lua_pushstring(L, get_key_name(&e, buf));
|
||||
return 2;
|
||||
|
||||
case SDL_KEYUP:
|
||||
case SDL_EVENT_KEY_UP:
|
||||
#ifdef __APPLE__
|
||||
/* on macos command+w will close the current window
|
||||
** we want to flush this event and let the keymapper
|
||||
** handle this key combination.
|
||||
** Thanks to mathewmariani, taken from his lite-macos github repository. */
|
||||
if ((e.key.keysym.sym == SDLK_w) && (e.key.keysym.mod & KMOD_GUI)) {
|
||||
SDL_FlushEvent(SDL_QUIT);
|
||||
if ((e.key.key == SDLK_W) && (e.key.mod & SDL_KMOD_GUI)) {
|
||||
SDL_FlushEvent(SDL_EVENT_QUIT);
|
||||
}
|
||||
#endif
|
||||
lua_pushstring(L, "keyreleased");
|
||||
lua_pushstring(L, get_key_name(&e, buf));
|
||||
return 2;
|
||||
|
||||
case SDL_TEXTINPUT:
|
||||
case SDL_EVENT_TEXT_INPUT:
|
||||
lua_pushstring(L, "textinput");
|
||||
lua_pushstring(L, e.text.text);
|
||||
return 2;
|
||||
|
||||
case SDL_TEXTEDITING:
|
||||
case SDL_EVENT_TEXT_EDITING:
|
||||
lua_pushstring(L, "textediting");
|
||||
lua_pushstring(L, e.edit.text);
|
||||
lua_pushinteger(L, e.edit.start);
|
||||
lua_pushinteger(L, e.edit.length);
|
||||
return 4;
|
||||
|
||||
#if SDL_VERSION_ATLEAST(2, 0, 22)
|
||||
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); }
|
||||
lua_pushstring(L, "mousepressed");
|
||||
lua_pushstring(L, button_name(e.button.button));
|
||||
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.clicks);
|
||||
return 5;
|
||||
|
||||
case SDL_MOUSEBUTTONUP:
|
||||
if (e.button.button == 1) { SDL_CaptureMouse(0); }
|
||||
lua_pushstring(L, "mousereleased");
|
||||
lua_pushstring(L, button_name(e.button.button));
|
||||
lua_pushinteger(L, e.button.x * window_renderer.scale_x);
|
||||
lua_pushinteger(L, e.button.y * window_renderer.scale_y);
|
||||
return 4;
|
||||
|
||||
case SDL_MOUSEMOTION:
|
||||
SDL_PumpEvents();
|
||||
while (SDL_PeepEvents(&event_plus, 1, SDL_GETEVENT, SDL_MOUSEMOTION, SDL_MOUSEMOTION) > 0) {
|
||||
e.motion.x = event_plus.motion.x;
|
||||
e.motion.y = event_plus.motion.y;
|
||||
e.motion.xrel += event_plus.motion.xrel;
|
||||
e.motion.yrel += event_plus.motion.yrel;
|
||||
case SDL_EVENT_MOUSE_BUTTON_DOWN:
|
||||
{
|
||||
if (e.button.button == 1) { SDL_CaptureMouse(1); }
|
||||
lua_pushstring(L, "mousepressed");
|
||||
lua_pushstring(L, button_name(e.button.button));
|
||||
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.clicks);
|
||||
return 5;
|
||||
}
|
||||
lua_pushstring(L, "mousemoved");
|
||||
lua_pushinteger(L, e.motion.x * window_renderer.scale_x);
|
||||
lua_pushinteger(L, e.motion.y * window_renderer.scale_y);
|
||||
lua_pushinteger(L, e.motion.xrel * window_renderer.scale_x);
|
||||
lua_pushinteger(L, e.motion.yrel * window_renderer.scale_y);
|
||||
return 5;
|
||||
|
||||
case SDL_MOUSEWHEEL:
|
||||
case SDL_EVENT_MOUSE_BUTTON_UP:
|
||||
{
|
||||
if (e.button.button == 1) { SDL_CaptureMouse(0); }
|
||||
lua_pushstring(L, "mousereleased");
|
||||
lua_pushstring(L, button_name(e.button.button));
|
||||
lua_pushinteger(L, e.button.x * window_renderer.scale_x);
|
||||
lua_pushinteger(L, e.button.y * window_renderer.scale_y);
|
||||
return 4;
|
||||
}
|
||||
|
||||
case SDL_EVENT_MOUSE_MOTION:
|
||||
{
|
||||
SDL_PumpEvents();
|
||||
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.y = event_plus.motion.y;
|
||||
e.motion.xrel += event_plus.motion.xrel;
|
||||
e.motion.yrel += event_plus.motion.yrel;
|
||||
}
|
||||
lua_pushstring(L, "mousemoved");
|
||||
lua_pushinteger(L, e.motion.x * window_renderer.scale_x);
|
||||
lua_pushinteger(L, e.motion.y * window_renderer.scale_y);
|
||||
lua_pushinteger(L, e.motion.xrel * window_renderer.scale_x);
|
||||
lua_pushinteger(L, e.motion.yrel * window_renderer.scale_y);
|
||||
return 5;
|
||||
}
|
||||
|
||||
case SDL_EVENT_MOUSE_WHEEL:
|
||||
lua_pushstring(L, "mousewheel");
|
||||
#if SDL_VERSION_ATLEAST(2, 0, 18)
|
||||
lua_pushnumber(L, e.wheel.preciseY);
|
||||
lua_pushnumber(L, e.wheel.y);
|
||||
// Use -x to keep consistency with vertical scrolling values (e.g. shift+scroll)
|
||||
lua_pushnumber(L, -e.wheel.preciseX);
|
||||
#else
|
||||
lua_pushinteger(L, e.wheel.y);
|
||||
lua_pushinteger(L, -e.wheel.x);
|
||||
#endif
|
||||
lua_pushnumber(L, -e.wheel.x);
|
||||
return 3;
|
||||
|
||||
case SDL_FINGERDOWN:
|
||||
SDL_GetWindowSize(window_renderer.window, &w, &h);
|
||||
case SDL_EVENT_FINGER_DOWN:
|
||||
{
|
||||
SDL_GetWindowSize(window_renderer.window, &w, &h);
|
||||
|
||||
lua_pushstring(L, "touchpressed");
|
||||
lua_pushinteger(L, (lua_Integer)(e.tfinger.x * w));
|
||||
lua_pushinteger(L, (lua_Integer)(e.tfinger.y * h));
|
||||
lua_pushinteger(L, e.tfinger.fingerId);
|
||||
return 4;
|
||||
|
||||
case SDL_FINGERUP:
|
||||
SDL_GetWindowSize(window_renderer.window, &w, &h);
|
||||
|
||||
lua_pushstring(L, "touchreleased");
|
||||
lua_pushinteger(L, (lua_Integer)(e.tfinger.x * w));
|
||||
lua_pushinteger(L, (lua_Integer)(e.tfinger.y * h));
|
||||
lua_pushinteger(L, e.tfinger.fingerId);
|
||||
return 4;
|
||||
|
||||
case SDL_FINGERMOTION:
|
||||
SDL_PumpEvents();
|
||||
while (SDL_PeepEvents(&event_plus, 1, SDL_GETEVENT, SDL_FINGERMOTION, SDL_FINGERMOTION) > 0) {
|
||||
e.tfinger.x = event_plus.tfinger.x;
|
||||
e.tfinger.y = event_plus.tfinger.y;
|
||||
e.tfinger.dx += event_plus.tfinger.dx;
|
||||
e.tfinger.dy += event_plus.tfinger.dy;
|
||||
lua_pushstring(L, "touchpressed");
|
||||
lua_pushinteger(L, (lua_Integer)(e.tfinger.x * w));
|
||||
lua_pushinteger(L, (lua_Integer)(e.tfinger.y * h));
|
||||
lua_pushinteger(L, e.tfinger.fingerID);
|
||||
return 4;
|
||||
}
|
||||
SDL_GetWindowSize(window_renderer.window, &w, &h);
|
||||
|
||||
lua_pushstring(L, "touchmoved");
|
||||
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.dx * w));
|
||||
lua_pushinteger(L, (lua_Integer)(e.tfinger.dy * h));
|
||||
lua_pushinteger(L, e.tfinger.fingerId);
|
||||
return 6;
|
||||
case SDL_EVENT_FINGER_UP:
|
||||
{
|
||||
SDL_GetWindowSize(window_renderer.window, &w, &h);
|
||||
|
||||
lua_pushstring(L, "touchreleased");
|
||||
lua_pushinteger(L, (lua_Integer)(e.tfinger.x * w));
|
||||
lua_pushinteger(L, (lua_Integer)(e.tfinger.y * h));
|
||||
lua_pushinteger(L, e.tfinger.fingerID);
|
||||
return 4;
|
||||
}
|
||||
|
||||
case SDL_EVENT_FINGER_MOTION:
|
||||
{
|
||||
SDL_PumpEvents();
|
||||
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.y = event_plus.tfinger.y;
|
||||
e.tfinger.dx += event_plus.tfinger.dx;
|
||||
e.tfinger.dy += event_plus.tfinger.dy;
|
||||
}
|
||||
SDL_GetWindowSize(window_renderer.window, &w, &h);
|
||||
|
||||
lua_pushstring(L, "touchmoved");
|
||||
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.dx * w));
|
||||
lua_pushinteger(L, (lua_Integer)(e.tfinger.dy * h));
|
||||
lua_pushinteger(L, e.tfinger.fingerID);
|
||||
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:
|
||||
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[] = {
|
||||
"arrow",
|
||||
@@ -393,11 +416,11 @@ static const char *cursor_opts[] = {
|
||||
};
|
||||
|
||||
static const int cursor_enums[] = {
|
||||
SDL_SYSTEM_CURSOR_ARROW,
|
||||
SDL_SYSTEM_CURSOR_IBEAM,
|
||||
SDL_SYSTEM_CURSOR_SIZEWE,
|
||||
SDL_SYSTEM_CURSOR_SIZENS,
|
||||
SDL_SYSTEM_CURSOR_HAND
|
||||
SDL_SYSTEM_CURSOR_DEFAULT,
|
||||
SDL_SYSTEM_CURSOR_TEXT,
|
||||
SDL_SYSTEM_CURSOR_EW_RESIZE,
|
||||
SDL_SYSTEM_CURSOR_NS_RESIZE,
|
||||
SDL_SYSTEM_CURSOR_POINTER
|
||||
};
|
||||
|
||||
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) {
|
||||
int n = luaL_checkoption(L, 1, "normal", window_opts);
|
||||
SDL_SetWindowFullscreen(window_renderer.window,
|
||||
n == WIN_FULLSCREEN ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0);
|
||||
SDL_SetWindowFullscreen(window_renderer.window, n == WIN_FULLSCREEN);
|
||||
if (n == WIN_NORMAL) { SDL_RestoreWindow(window_renderer.window); }
|
||||
if (n == WIN_MAXIMIZED) { SDL_MaximizeWindow(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) {
|
||||
int bordered = lua_toboolean(L, 1);
|
||||
SDL_SetWindowBordered(window_renderer.window, bordered);
|
||||
SDL_SetWindowBordered(window_renderer.window, lua_toboolean(L, 1));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
return 0;
|
||||
}
|
||||
window_hit_info->title_height = luaL_checknumber(L, 1);
|
||||
window_hit_info->controls_width = luaL_checknumber(L, 2);
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -487,7 +508,7 @@ static int f_window_has_focus(lua_State *L) {
|
||||
|
||||
static int f_get_window_mode(lua_State *L) {
|
||||
unsigned flags = SDL_GetWindowFlags(window_renderer.window);
|
||||
if (flags & SDL_WINDOW_FULLSCREEN_DESKTOP) {
|
||||
if (flags & SDL_WINDOW_FULLSCREEN) {
|
||||
lua_pushstring(L, "fullscreen");
|
||||
} else if (flags & SDL_WINDOW_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.w = luaL_checknumber(L, 3);
|
||||
rect.h = luaL_checknumber(L, 4);
|
||||
SDL_SetTextInputRect(&rect);
|
||||
SDL_SetTextInputArea(window_renderer.window, &rect, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int f_clear_ime(lua_State *L) {
|
||||
#if SDL_VERSION_ATLEAST(2, 0, 22)
|
||||
SDL_ClearComposition();
|
||||
#endif
|
||||
SDL_ClearComposition(window_renderer.window);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
return 0;
|
||||
}
|
||||
@@ -545,31 +557,11 @@ static int f_show_fatal_error(lua_State *L) {
|
||||
|
||||
// removes an empty directory
|
||||
static int f_rmdir(lua_State *L) {
|
||||
const char *path = luaL_checkstring(L, 1);
|
||||
|
||||
#ifdef _WIN32
|
||||
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());
|
||||
lua_pushboolean(L, SDL_RemovePath(luaL_checkstring(L, 1)));
|
||||
if (!lua_toboolean(L, -1)) {
|
||||
lua_pushstring(L, SDL_GetError());
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -590,80 +582,24 @@ static int f_chdir(lua_State *L) {
|
||||
|
||||
|
||||
static int f_list_dir(lua_State *L) {
|
||||
int count = 0;
|
||||
const char *path = luaL_checkstring(L, 1);
|
||||
|
||||
#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);
|
||||
char **dir = SDL_GlobDirectory(path, NULL, 0, &count);
|
||||
if (!dir) {
|
||||
lua_pushnil(L);
|
||||
lua_pushstring(L, strerror(errno));
|
||||
lua_pushstring(L, SDL_GetError());
|
||||
return 2;
|
||||
}
|
||||
|
||||
lua_newtable(L);
|
||||
int i = 1;
|
||||
struct dirent *entry;
|
||||
while ( (entry = readdir(dir)) ) {
|
||||
if (strcmp(entry->d_name, "." ) == 0) { continue; }
|
||||
if (strcmp(entry->d_name, "..") == 0) { continue; }
|
||||
lua_pushstring(L, entry->d_name);
|
||||
lua_rawseti(L, -2, i);
|
||||
i++;
|
||||
lua_createtable(L, count, 0);
|
||||
for (int ti = 1, i = 0; i < count; i++) {
|
||||
if (strcmp(dir[i], ".") == 0) continue;
|
||||
if (strcmp(dir[i], "..") == 0) continue;
|
||||
lua_pushstring(L, dir[i]);
|
||||
lua_rawseti(L, -2, ti++);
|
||||
}
|
||||
|
||||
closedir(dir);
|
||||
SDL_free(dir);
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
+23
-40
@@ -1,6 +1,7 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <SDL.h>
|
||||
#include <SDL3/SDL.h>
|
||||
#include <SDL3/SDL_main.h>
|
||||
#include "api/api.h"
|
||||
#include "rencache.h"
|
||||
#include "renderer.h"
|
||||
@@ -11,7 +12,7 @@
|
||||
#include <windows.h>
|
||||
#elif defined(__linux__)
|
||||
#include <unistd.h>
|
||||
#elif defined(__APPLE__)
|
||||
#elif defined(SDL_PLATFORM_APPLE)
|
||||
#include <mach-o/dyld.h>
|
||||
#elif defined(__FreeBSD__)
|
||||
#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);
|
||||
if (len > 0)
|
||||
buf[len] = '\0';
|
||||
#elif __APPLE__
|
||||
#elif SDL_PLATFORM_APPLE
|
||||
/* 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
|
||||
** /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__)
|
||||
#include "../resources/icons/icon.inl"
|
||||
(void) icon_rgba_len; /* unused */
|
||||
SDL_Surface *surf = SDL_CreateRGBSurfaceFrom(
|
||||
icon_rgba, 64, 64,
|
||||
32, 64 * 4,
|
||||
0x000000ff,
|
||||
0x0000ff00,
|
||||
0x00ff0000,
|
||||
0xff000000);
|
||||
SDL_PixelFormat format = SDL_GetPixelFormatForMasks(32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000);
|
||||
SDL_Surface *surf = SDL_CreateSurfaceFrom(64, 64, format, icon_rgba, 64 * 4);
|
||||
SDL_SetWindowIcon(window, surf);
|
||||
SDL_FreeSurface(surf);
|
||||
SDL_DestroySurface(surf);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -83,7 +79,7 @@ static void init_window_icon(void) {
|
||||
#define LITE_NONPATHSEP_PATTERN "[^/]+"
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
#ifdef SDL_PLATFORM_APPLE
|
||||
void enable_momentum_scroll();
|
||||
#ifdef MACOS_USE_BUNDLE
|
||||
void set_macos_bundle_resources(lua_State *L);
|
||||
@@ -108,7 +104,7 @@ void set_macos_bundle_resources(lua_State *L);
|
||||
#define ARCH_PLATFORM "linux"
|
||||
#elif __FreeBSD__
|
||||
#define ARCH_PLATFORM "freebsd"
|
||||
#elif __APPLE__
|
||||
#elif SDL_PLATFORM_APPLE
|
||||
#define ARCH_PLATFORM "darwin"
|
||||
#endif
|
||||
|
||||
@@ -124,53 +120,38 @@ int main(int argc, char **argv) {
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
#endif
|
||||
|
||||
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS) != 0) {
|
||||
fprintf(stderr, "Error initializing SDL: %s\n", SDL_GetError());
|
||||
if (!SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS)) {
|
||||
fprintf(stderr, "Error initializing SDL: %s", SDL_GetError());
|
||||
exit(1);
|
||||
}
|
||||
SDL_EnableScreenSaver();
|
||||
SDL_EventState(SDL_DROPFILE, SDL_ENABLE);
|
||||
SDL_SetEventEnabled(SDL_EVENT_DROP_FILE, true);
|
||||
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");
|
||||
#endif
|
||||
#if SDL_VERSION_ATLEAST(2, 0, 5)
|
||||
SDL_SetHint(SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH, "1");
|
||||
#endif
|
||||
#if SDL_VERSION_ATLEAST(2, 0, 18)
|
||||
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
|
||||
SDL_SetHint(SDL_HINT_IME_IMPLEMENTED_UI, "1");
|
||||
SDL_SetHint(SDL_HINT_RENDER_DRIVER, "software");
|
||||
|
||||
#if SDL_VERSION_ATLEAST(2, 0, 8)
|
||||
/* 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
|
||||
** of obscuring it. */
|
||||
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.
|
||||
** It also enables aero-snap on Windows apparently. */
|
||||
SDL_SetHint("SDL_BORDERLESS_RESIZABLE_STYLE", "1");
|
||||
#endif
|
||||
#if SDL_VERSION_ATLEAST(2, 0, 9)
|
||||
SDL_SetHint("SDL_MOUSE_DOUBLE_CLICK_RADIUS", "4");
|
||||
#endif
|
||||
|
||||
SDL_DisplayMode dm;
|
||||
SDL_GetCurrentDisplayMode(0, &dm);
|
||||
SDL_SetHint(SDL_HINT_MOUSE_DOUBLE_CLICK_RADIUS, "4");
|
||||
|
||||
const SDL_DisplayMode* dm = SDL_GetCurrentDisplayMode(SDL_GetPrimaryDisplay());
|
||||
window = SDL_CreateWindow(
|
||||
"", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, dm.w * 0.8, dm.h * 0.8,
|
||||
SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI | SDL_WINDOW_HIDDEN);
|
||||
init_window_icon();
|
||||
"", (dm ? dm->w : 2) * 0.8, (dm ? dm->h : 2) * 0.8,
|
||||
SDL_WINDOW_RESIZABLE | SDL_WINDOW_HIGH_PIXEL_DENSITY | SDL_WINDOW_HIDDEN);
|
||||
if (!window) {
|
||||
fprintf(stderr, "Error creating lite-xl window: %s", SDL_GetError());
|
||||
exit(1);
|
||||
}
|
||||
init_window_icon();
|
||||
|
||||
if (ren_init(window) != 0) {
|
||||
fprintf(stderr, "Error initializing renderer: %s\n", SDL_GetError());
|
||||
exit(1);
|
||||
@@ -206,12 +187,14 @@ init_lua:
|
||||
}
|
||||
lua_setglobal(L, "EXEFILE");
|
||||
|
||||
#ifdef __APPLE__
|
||||
#ifdef SDL_PLATFORM_APPLE
|
||||
enable_momentum_scroll();
|
||||
#ifdef MACOS_USE_BUNDLE
|
||||
set_macos_bundle_resources(L);
|
||||
#endif
|
||||
#endif
|
||||
SDL_SetEventEnabled(SDL_EVENT_TEXT_INPUT, true);
|
||||
SDL_SetEventEnabled(SDL_EVENT_TEXT_EDITING, true);
|
||||
|
||||
const char *init_lite_code = \
|
||||
"local core\n"
|
||||
|
||||
+2
-60
@@ -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
|
||||
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_deps = [lua_dep, sdl_dep, freetype_dep, pcre2_dep, libm, libdl]
|
||||
|
||||
lite_sources += 'api/dirmonitor.c'
|
||||
# dirmonitor backend
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
+46
-35
@@ -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 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) {
|
||||
case EGlyphFormatSubpixel: *depth = 24; return SDL_PIXELFORMAT_RGB24;
|
||||
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;
|
||||
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)
|
||||
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--) {
|
||||
assert(atlas->surfaces[i]->userdata);
|
||||
GlyphMetric *m = (GlyphMetric *) atlas->surfaces[i]->userdata;
|
||||
userdata = SDL_GetSurfaceProperties(atlas->surfaces[i]);
|
||||
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;
|
||||
if (new_min_waste >= metric->y1 && new_min_waste < min_waste) {
|
||||
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;
|
||||
if (h <= FONT_HEIGHT_OVERFLOW_PX) h += slot->bitmap.rows;
|
||||
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[atlas->nsurface] = check_alloc(SDL_CreateRGBSurfaceWithFormat(0, atlas->width, GLYPHS_PER_ATLAS * h, depth, format));
|
||||
atlas->surfaces[atlas->nsurface]->userdata = NULL;
|
||||
atlas->surfaces[atlas->nsurface] = check_alloc(SDL_CreateSurface(atlas->width, GLYPHS_PER_ATLAS * h, format));
|
||||
userdata = SDL_GetSurfaceProperties(atlas->surfaces[atlas->nsurface]);
|
||||
SDL_SetPointerProperty(userdata, "metric", NULL);
|
||||
surface_idx = atlas->nsurface++;
|
||||
font->glyphs.bytesize += (sizeof(SDL_Surface *) + sizeof(SDL_Surface) + atlas->width * GLYPHS_PER_ATLAS * h * glyph_format);
|
||||
}
|
||||
metric->surface_idx = surface_idx;
|
||||
if (atlas->surfaces[surface_idx]->userdata) {
|
||||
GlyphMetric *last_metric = (GlyphMetric *) atlas->surfaces[surface_idx]->userdata;
|
||||
userdata = SDL_GetSurfaceProperties(atlas->surfaces[surface_idx]);
|
||||
if (SDL_HasProperty(userdata, "metric")) {
|
||||
GlyphMetric *last_metric = (GlyphMetric *) SDL_GetPointerProperty(userdata, "metric", NULL);
|
||||
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];
|
||||
}
|
||||
|
||||
@@ -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++) {
|
||||
GlyphAtlas *atlas = &font->glyphs.atlas[glyph_format_idx][atlas_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);
|
||||
}
|
||||
@@ -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
|
||||
static unsigned long font_file_read(FT_Stream stream, unsigned long offset, unsigned char *buffer, unsigned long count) {
|
||||
uint64_t amount;
|
||||
SDL_RWops *file = (SDL_RWops *) stream->descriptor.pointer;
|
||||
SDL_RWseek(file, (int) offset, RW_SEEK_SET);
|
||||
SDL_IOStream *file = (SDL_IOStream *) stream->descriptor.pointer;
|
||||
SDL_SeekIO(file, (int) offset, SDL_IO_SEEK_SET);
|
||||
if (count == 0)
|
||||
return 0;
|
||||
amount = SDL_RWread(file, buffer, sizeof(char), count);
|
||||
amount = SDL_ReadIO(file, buffer, sizeof(char) * count);
|
||||
if (amount <= 0)
|
||||
return 0;
|
||||
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) {
|
||||
if (stream && stream->descriptor.pointer)
|
||||
SDL_RWclose((SDL_RWops *) stream->descriptor.pointer);
|
||||
SDL_CloseIO((SDL_IOStream *) stream->descriptor.pointer);
|
||||
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) {
|
||||
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;
|
||||
|
||||
SDL_ClearError();
|
||||
|
||||
file = SDL_RWFromFile(path, "rb");
|
||||
if (!file) return NULL; // error set by SDL_RWFromFile
|
||||
file = SDL_IOFromFile(path, "rb");
|
||||
if (!file) return NULL; // error set by SDL_IOFromFile
|
||||
|
||||
int len = strlen(path);
|
||||
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->descriptor.pointer = file;
|
||||
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)
|
||||
goto failure;
|
||||
@@ -488,7 +491,7 @@ RenFont* ren_font_load(RenWindow *window_renderer, const char* path, float size,
|
||||
return font;
|
||||
|
||||
stream_failure:
|
||||
if (file) SDL_RWclose(file);
|
||||
if (file) SDL_CloseIO(file);
|
||||
failure:
|
||||
if (err != FT_Err_Ok) SDL_SetError("%s", get_ft_error(err));
|
||||
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) {
|
||||
SDL_Surface *surface = rs->surface;
|
||||
SDL_Rect clip;
|
||||
SDL_GetClipRect(surface, &clip);
|
||||
SDL_GetSurfaceClipRect(surface, &clip);
|
||||
|
||||
const int surface_scale = rs->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;
|
||||
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) {
|
||||
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
|
||||
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;
|
||||
|
||||
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;
|
||||
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
|
||||
*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 };
|
||||
|
||||
if (color.a == 0xff) {
|
||||
uint32_t translated = SDL_MapRGB(surface->format, color.r, color.g, color.b);
|
||||
SDL_FillRect(surface, &dest_rect, translated);
|
||||
uint32_t translated = SDL_MapSurfaceRGB(surface, color.r, color.g, color.b);
|
||||
SDL_FillSurfaceRect(surface, &dest_rect, translated);
|
||||
} else {
|
||||
// Seems like SDL doesn't handle clipping as we expect when using
|
||||
// scaled blitting, so we "clip" manually.
|
||||
SDL_Rect clip;
|
||||
SDL_GetClipRect(surface, &clip);
|
||||
if (!SDL_IntersectRect(&clip, &dest_rect, &dest_rect)) return;
|
||||
SDL_GetSurfaceClipRect(surface, &clip);
|
||||
if (!SDL_GetRectIntersection(&clip, &dest_rect, &dest_rect)) return;
|
||||
|
||||
uint32_t *pixel = (uint32_t *)draw_rect_surface->pixels;
|
||||
*pixel = SDL_MapRGBA(draw_rect_surface->format, color.r, color.g, color.b, color.a);
|
||||
SDL_BlitScaled(draw_rect_surface, NULL, surface, &dest_rect);
|
||||
*pixel = SDL_MapSurfaceRGBA(draw_rect_surface, color.r, color.g, color.b, color.a);
|
||||
SDL_BlitSurfaceScaled(draw_rect_surface, NULL, surface, &dest_rect, SDL_SCALEMODE_LINEAR);
|
||||
}
|
||||
}
|
||||
|
||||
/*************** Window Management ****************/
|
||||
void ren_free_window_resources(RenWindow *window_renderer) {
|
||||
renwin_free(window_renderer);
|
||||
SDL_FreeSurface(draw_rect_surface);
|
||||
SDL_DestroySurface(draw_rect_surface);
|
||||
free(window_renderer->command_buf);
|
||||
window_renderer->command_buf = NULL;
|
||||
window_renderer->command_buf_size = 0;
|
||||
@@ -734,8 +745,8 @@ int ren_init(SDL_Window *win) {
|
||||
SDL_ClearError();
|
||||
assert(win);
|
||||
|
||||
draw_rect_surface = SDL_CreateRGBSurface(0, 1, 1, 32,
|
||||
0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF);
|
||||
draw_rect_surface = SDL_CreateSurface(1, 1, SDL_PIXELFORMAT_RGBA32);
|
||||
|
||||
if (!draw_rect_surface)
|
||||
return -1; // error set by SDL_CreateRGBSurface
|
||||
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
#ifndef RENDERER_H
|
||||
#define RENDERER_H
|
||||
|
||||
#include <SDL.h>
|
||||
#include <SDL3/SDL.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
|
||||
+16
-14
@@ -1,3 +1,4 @@
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include "renwindow.h"
|
||||
@@ -6,7 +7,7 @@
|
||||
static int query_surface_scale(RenWindow *ren) {
|
||||
int w_pixels, h_pixels;
|
||||
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);
|
||||
/* We consider that the ratio pixel/point will always be an integer and
|
||||
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) {
|
||||
/* 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) {
|
||||
ren->renderer = SDL_CreateRenderer(ren->window, -1, 0);
|
||||
ren->renderer = SDL_CreateRenderer(ren->window, NULL);
|
||||
}
|
||||
if (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);
|
||||
}
|
||||
#endif
|
||||
@@ -33,11 +34,12 @@ void renwin_init_surface(RenWindow *ren) {
|
||||
ren->scale_x = ren->scale_y = 1;
|
||||
#ifdef LITE_USE_SDL_RENDERER
|
||||
if (ren->rensurface.surface) {
|
||||
SDL_FreeSurface(ren->rensurface.surface);
|
||||
SDL_DestroySurface(ren->rensurface.surface);
|
||||
}
|
||||
int w, h;
|
||||
SDL_GL_GetDrawableSize(ren->window, &w, &h);
|
||||
ren->rensurface.surface = SDL_CreateRGBSurfaceWithFormat(0, w, h, 32, SDL_PIXELFORMAT_BGRA32);
|
||||
SDL_GetWindowSizeInPixels(ren->window, &w, &h);
|
||||
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) {
|
||||
fprintf(stderr, "Error creating surface: %s", SDL_GetError());
|
||||
exit(1);
|
||||
@@ -59,14 +61,14 @@ static RenRect scaled_rect(const RenRect rect, const int scale) {
|
||||
|
||||
|
||||
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) {
|
||||
RenSurface rs = renwin_get_surface(ren);
|
||||
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) {
|
||||
#ifdef LITE_USE_SDL_RENDERER
|
||||
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);
|
||||
/* Note that (w, h) may differ from (new_w, new_h) on retina displays. */
|
||||
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 w = scale * r->width, h = scale * r->height;
|
||||
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;
|
||||
SDL_UpdateTexture(ren->texture, &sr, pixels, ren->rensurface.surface->w * 4);
|
||||
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->pitch);
|
||||
}
|
||||
SDL_RenderCopy(ren->renderer, ren->texture, NULL, NULL);
|
||||
SDL_RenderTexture(ren->renderer, ren->texture, NULL, NULL);
|
||||
SDL_RenderPresent(ren->renderer);
|
||||
#else
|
||||
SDL_UpdateWindowSurfaceRects(ren->window, (SDL_Rect*) rects, count);
|
||||
@@ -135,7 +137,7 @@ void renwin_free(RenWindow *ren) {
|
||||
#ifdef LITE_USE_SDL_RENDERER
|
||||
SDL_DestroyTexture(ren->texture);
|
||||
SDL_DestroyRenderer(ren->renderer);
|
||||
SDL_FreeSurface(ren->rensurface.surface);
|
||||
SDL_DestroySurface(ren->rensurface.surface);
|
||||
#endif
|
||||
SDL_DestroyWindow(ren->window);
|
||||
ren->window = NULL;
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
#include <SDL.h>
|
||||
#include <SDL3/SDL.h>
|
||||
#include "renderer.h"
|
||||
|
||||
struct RenWindow {
|
||||
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user