This commit is contained in:
Thomas Peterson 2025-10-25 22:04:24 +02:00
parent 6b021058c6
commit 6e1b7c2b1b
53 changed files with 59099 additions and 116 deletions

View File

@ -2,6 +2,8 @@
require_once __DIR__ . '/../vendor/autoload.php';
define('DEBUG_EVENTS', false);
use PHPNative\Framework\Application;
use PHPNative\Ui\Widget\Button;
use PHPNative\Ui\Widget\Container;
@ -20,22 +22,22 @@ $mainContainer = new Container('flex flex-col p-6 gap-4 bg-gray-50');
$title = new Label(
text: 'Advanced Multi-Window Demo',
style: 'text-2xl text-gray-900'
style: 'text-2xl text-gray-900',
);
$subtitle = new Label(
text: 'Windows mit asynchronen Operationen',
style: 'text-base text-gray-600'
style: 'text-base text-gray-600',
);
// Button to create window with async data loading
$createAsyncWindowButton = new Button(
text: 'Window mit Async-Datenladung',
style: 'bg-purple-500 hover:bg-purple-700 text-white p-4 rounded-lg'
style: 'bg-purple-500 hover:bg-purple-700 text-white p-4 rounded-lg',
);
$createAsyncWindowButton->setOnClickAsync(
onClickAsync: function() use (&$windowCounter) {
onClickAsync: function () use (&$windowCounter) {
// Simulate loading data in background
sleep(1);
@ -43,49 +45,49 @@ $createAsyncWindowButton->setOnClickAsync(
'windowId' => $windowCounter++,
'data' => 'Daten erfolgreich geladen!',
'timestamp' => date('H:i:s'),
'items' => ['Item 1', 'Item 2', 'Item 3']
'items' => ['Item 1', 'Item 2', 'Item 3'],
];
},
onComplete: function($result) use ($app) {
onComplete: function ($result) use ($app) {
// Create window with loaded data
$windowId = $result['windowId'];
$newWindow = $app->createWindow(
"Data Window #$windowId",
"Data Window #{$windowId}",
500,
350,
150 + ($windowId * 30),
150 + ($windowId * 30)
150 + ($windowId * 30),
);
$container = new Container('flex flex-col p-6 gap-3 bg-green-50');
$titleLabel = new Label(
text: "Data Window #$windowId",
style: 'text-xl text-gray-900'
text: "Data Window #{$windowId}",
style: 'text-xl text-gray-900',
);
$dataLabel = new Label(
text: $result['data'],
style: 'text-base text-green-700 p-2 bg-white rounded'
style: 'text-base text-green-700 p-2 bg-white rounded',
);
$timeLabel = new Label(
text: "Geladen um: " . $result['timestamp'],
style: 'text-sm text-gray-600'
text: 'Geladen um: ' . $result['timestamp'],
style: 'text-sm text-gray-600',
);
$itemsLabel = new Label(
text: "Items:\n" . implode("\n", $result['items']),
style: 'text-sm text-gray-700 p-2 bg-white rounded'
style: 'text-sm text-gray-700 p-2 bg-white rounded',
);
$closeButton = new Button(
text: 'Schließen',
style: 'bg-red-500 hover:bg-red-700 text-white p-3 rounded'
style: 'bg-red-500 hover:bg-red-700 text-white p-3 rounded',
);
$closeButton->setOnClick(function() use ($newWindow) {
$closeButton->setOnClick(function () use ($newWindow) {
$newWindow->close();
});
@ -98,48 +100,42 @@ $createAsyncWindowButton->setOnClickAsync(
$newWindow->setRoot($container);
},
onError: function($error) {
error_log("Error creating window: " . $error->getMessage());
}
onError: function ($error) {
error_log('Error creating window: ' . $error->getMessage());
},
);
// Button to create multiple windows at once
$createMultipleButton = new Button(
text: '3 Windows auf einmal erstellen',
style: 'bg-orange-500 hover:bg-orange-700 text-white p-4 rounded-lg'
style: 'bg-orange-500 hover:bg-orange-700 text-white p-4 rounded-lg',
);
$createMultipleButton->setOnClick(function() use ($app, &$windowCounter) {
$createMultipleButton->setOnClick(function () use ($app, &$windowCounter) {
for ($i = 0; $i < 3; $i++) {
$currentId = $windowCounter++;
$offset = $currentId * 40;
$newWindow = $app->createWindow(
"Batch Window #$currentId",
400,
250,
200 + $offset,
200 + ($i * 50)
);
$newWindow = $app->createWindow("Batch Window #{$currentId}", 400, 250, 200 + $offset, 200 + ($i * 50));
$container = new Container('flex flex-col p-4 gap-2 bg-yellow-50');
$label = new Label(
text: "Batch Window #$currentId",
style: 'text-lg text-gray-900'
text: "Batch Window #{$currentId}",
style: 'text-lg text-gray-900',
);
$info = new Label(
text: "Teil einer Batch-Erstellung ($i/3)",
style: 'text-sm text-gray-600'
text: "Teil einer Batch-Erstellung ({$i}/3)",
style: 'text-sm text-gray-600',
);
$closeButton = new Button(
text: 'X',
style: 'bg-red-500 hover:bg-red-700 text-white p-2 rounded'
style: 'bg-red-500 hover:bg-red-700 text-white p-2 rounded',
);
$closeButton->setOnClick(function() use ($newWindow) {
$closeButton->setOnClick(function () use ($newWindow) {
$newWindow->close();
});
@ -154,7 +150,7 @@ $createMultipleButton->setOnClick(function() use ($app, &$windowCounter) {
// Window count label
$windowCountLabel = new Label(
text: 'Offene Windows: 1',
style: 'text-sm text-blue-600 p-2 bg-white rounded'
style: 'text-sm text-blue-600 p-2 bg-white rounded',
);
// Update window count periodically
@ -167,17 +163,17 @@ $mainContainer->addComponent($createMultipleButton);
// Info
$info = new Label(
text: 'Die UI bleibt responsive während des Ladens!',
style: 'text-xs text-gray-500 italic mt-4'
style: 'text-xs text-gray-500 italic mt-4',
);
$mainContainer->addComponent($info);
// Quit button
$quitButton = new Button(
text: 'Beenden',
style: 'bg-red-600 hover:bg-red-800 text-white p-4 rounded-lg'
style: 'bg-red-600 hover:bg-red-800 text-white p-4 rounded-lg',
);
$quitButton->setOnClick(function() use ($app) {
$quitButton->setOnClick(function () use ($app) {
$app->quit();
});

View File

@ -0,0 +1,160 @@
<?php
/**
* Multi-Process Window Example
*
* Each window runs in a separate process (not thread!)
* This works because each process has its own main thread for OpenGL
*/
require_once __DIR__ . '/../vendor/autoload.php';
use PHPNative\Framework\Application;
use PHPNative\Ui\Widget\Button;
use PHPNative\Ui\Widget\Container;
use PHPNative\Ui\Widget\Label;
// Check if we're the main process or a child
$windowId = $argv[1] ?? null;
if ($windowId === null) {
// MAIN PROCESS - Launch child processes
echo "Main Process: Launching 2 window processes...\n\n";
$pids = [];
// Launch Window 1 process
$pid1 = pcntl_fork();
if ($pid1 == -1) {
die("Could not fork for Window 1\n");
} elseif ($pid1 == 0) {
// Child process 1
runWindow('1', 'Window 1 - Blue', 100, 100, 'blue');
exit(0);
} else {
$pids[] = $pid1;
echo "Main Process: Window 1 started with PID $pid1\n";
}
// Small delay to avoid race conditions
usleep(100000);
// Launch Window 2 process
$pid2 = pcntl_fork();
if ($pid2 == -1) {
die("Could not fork for Window 2\n");
} elseif ($pid2 == 0) {
// Child process 2
runWindow('2', 'Window 2 - Green', 550, 100, 'green');
exit(0);
} else {
$pids[] = $pid2;
echo "Main Process: Window 2 started with PID $pid2\n";
}
echo "\nMain Process: Both windows launched!\n";
echo "Main Process: Waiting for child processes to exit...\n\n";
// Wait for all child processes
foreach ($pids as $pid) {
$status = 0;
pcntl_waitpid($pid, $status);
echo "Main Process: Child process $pid exited\n";
}
echo "\nMain Process: All windows closed. Exiting.\n";
} else {
// This shouldn't happen in fork mode
die("Error: Unexpected command line argument\n");
}
/**
* Run a single window in this process
*/
function runWindow(string $id, string $title, int $x, int $y, string $bgColor): void
{
echo "Process $id: Creating window '$title'\n";
// Create application
$app = new Application();
// Create window
$window = $app->createWindow($title, 400, 350, $x, $y);
// Create UI
$container = new Container("flex flex-col p-6 gap-4 bg-$bgColor-100");
$titleLabel = new Label(
text: $title,
style: "text-2xl text-$bgColor-900"
);
$processLabel = new Label(
text: 'Process ID: ' . getmypid(),
style: "text-sm text-$bgColor-700"
);
$frameLabel = new Label(
text: 'Frame: 0',
style: "text-base text-$bgColor-600"
);
$button = new Button(
text: 'Click Me!',
style: "bg-$bgColor-500 hover:bg-$bgColor-700 text-white p-4 rounded-lg"
);
$clickCount = 0;
$button->setOnClick(function() use (&$clickCount, $button, $title) {
$clickCount++;
$button->setText("Clicked $clickCount times");
echo "$title - Button clicked! Count: $clickCount\n";
});
$closeButton = new Button(
text: 'Close Window',
style: "bg-red-500 hover:bg-red-700 text-white p-3 rounded"
);
$closeButton->setOnClick(function() use ($window) {
echo "Close button clicked!\n";
$window->close();
});
$container->addComponent($titleLabel);
$container->addComponent($processLabel);
$container->addComponent($frameLabel);
$container->addComponent($button);
$container->addComponent($closeButton);
$window->setRoot($container);
echo "Process $id: Starting event loop\n";
// Run the window
$frameCount = 0;
while (!$window->shouldClose()) {
$frameCount++;
$frameLabel->setText("Frame: $frameCount");
$window->layout();
// Poll events
rgfw_pollEvents();
$window->handleEvents();
// Update
\PHPNative\Async\TaskManager::getInstance()->update();
$window->update();
// Render
$window->render();
// ~60 FPS
usleep(16666);
}
// Cleanup
echo "Process $id: Window closed after $frameCount frames\n";
$window->cleanup();
}

View File

@ -0,0 +1,153 @@
<?php
/**
* Example with 2 framework windows running in parallel threads
* Requires: parallel extension
*
* Note: Each window runs in its own thread with its own event loop
*/
require_once __DIR__ . '/../vendor/autoload.php';
use parallel\Runtime;
use PHPNative\Framework\Application;
use PHPNative\Ui\Widget\Button;
use PHPNative\Ui\Widget\Container;
use PHPNative\Ui\Widget\Label;
// Check if parallel extension is loaded
if (!extension_loaded('parallel')) {
die("Error: parallel extension is not loaded. Install with: pecl install parallel\n");
}
echo "Starting 2 framework windows in parallel threads...\n\n";
/**
* Function to run a window with the framework in a thread
*/
$windowRunner = function(string $title, int $x, int $y, string $bgColor) {
require_once __DIR__ . '/../vendor/autoload.php';
// Create application for this thread
$app = new \PHPNative\Framework\Application();
// Create window
$window = $app->createWindow($title, 400, 350, $x, $y);
// Create UI
$container = new \PHPNative\Ui\Widget\Container("flex flex-col p-6 gap-4 bg-$bgColor-100");
$titleLabel = new \PHPNative\Ui\Widget\Label(
text: $title,
style: "text-2xl text-$bgColor-900"
);
$infoLabel = new \PHPNative\Ui\Widget\Label(
text: 'Running in separate thread',
style: "text-sm text-$bgColor-700"
);
$frameLabel = new \PHPNative\Ui\Widget\Label(
text: 'Frame: 0',
style: "text-base text-$bgColor-600"
);
$button = new \PHPNative\Ui\Widget\Button(
text: 'Click Me!',
style: "bg-$bgColor-500 hover:bg-$bgColor-700 text-white p-4 rounded-lg"
);
$clickCount = 0;
$button->setOnClick(function() use (&$clickCount, $button, $title) {
$clickCount++;
$button->setText("Clicked $clickCount times");
echo "$title - Button clicked! Count: $clickCount\n";
});
$closeButton = new \PHPNative\Ui\Widget\Button(
text: 'Close Window',
style: "bg-red-500 hover:bg-red-700 text-white p-3 rounded"
);
$closeButton->setOnClick(function() use ($window) {
$window->close();
});
$container->addComponent($titleLabel);
$container->addComponent($infoLabel);
$container->addComponent($frameLabel);
$container->addComponent($button);
$container->addComponent($closeButton);
$window->setRoot($container);
// Custom run loop with frame counter
$frameCount = 0;
while (!$window->shouldClose()) {
$frameCount++;
$frameLabel->setText("Frame: $frameCount");
$window->layout();
// Poll events
rgfw_pollEvents();
$window->handleEvents();
// Update
\PHPNative\Async\TaskManager::getInstance()->update();
$window->update();
// Render
$window->render();
// ~60 FPS
usleep(16666);
}
// Cleanup
$window->cleanup();
return "$title closed after $frameCount frames";
};
try {
// Launch Window 1 (Blue) in thread
echo "Launching Window 1 (Blue) in thread...\n";
$runtime1 = new Runtime();
$future1 = $runtime1->run($windowRunner, [
'Window 1 - Blue',
100,
100,
'blue'
]);
// Launch Window 2 (Green) in thread
echo "Launching Window 2 (Green) in thread...\n";
$runtime2 = new Runtime();
$future2 = $runtime2->run($windowRunner, [
'Window 2 - Green',
550,
100,
'green'
]);
echo "\nBoth windows launched in parallel threads!\n";
echo "Each window has its own event loop\n";
echo "Try clicking the buttons and closing windows\n";
echo "Main thread waiting for windows to close...\n\n";
// Wait for both windows to complete
echo "Waiting for Window 1...\n";
$result1 = $future1->value();
echo $result1 . "\n";
echo "Waiting for Window 2...\n";
$result2 = $future2->value();
echo $result2 . "\n";
echo "\nAll windows closed. Application exiting.\n";
} catch (\Throwable $e) {
echo "Error: " . $e->getMessage() . "\n";
echo "Stack trace:\n" . $e->getTraceAsString() . "\n";
}

View File

@ -0,0 +1,170 @@
<?php
/**
* Simple example with 2 windows running in parallel threads
* Requires: parallel extension
*/
require_once __DIR__ . '/../vendor/autoload.php';
use parallel\Runtime;
use parallel\Channel;
// Check if parallel extension is loaded
if (!extension_loaded('parallel')) {
die("Error: parallel extension is not loaded. Install with: pecl install parallel\n");
}
echo "Starting 2 windows in parallel threads...\n";
echo "Each window runs independently in its own thread\n";
echo "Press ESC or close button to exit each window\n\n";
/**
* Window function that runs in a thread
*/
$windowFunction = function(string $title, int $x, int $y, int $width, int $height, array $bgColor) {
// Enable event queue mode
rgfw_setQueueEvents(true);
// Create window
$window = rgfw_createWindow($title, $x, $y, $width, $height, 0);
if (!$window) {
throw new \Exception("Failed to create window: $title");
}
// Initialize RSGL renderer
if (!rsgl_init($window)) {
throw new \Exception("Failed to initialize RSGL for: $title");
}
[$r, $g, $b] = $bgColor;
$running = true;
$frameCount = 0;
$mouseX = 0;
$mouseY = 0;
$isHovering = false;
while ($running) {
// Poll events for this window
rgfw_pollEvents();
// Process queued events
while ($event = rgfw_window_checkQueuedEvent($window)) {
switch ($event['type']) {
case RGFW_quit:
$running = false;
break;
case RGFW_keyPressed:
$keyCode = $event['keyCode'] ?? 0;
if ($keyCode == RGFW_Escape) {
$running = false;
}
break;
case RGFW_mousePosChanged:
$mouseX = $event[0] ?? 0;
$mouseY = $event[1] ?? 0;
// Check if hovering over center rectangle
$rectSize = 100;
$rectX = ($width / 2) - ($rectSize / 2);
$rectY = ($height / 2) - ($rectSize / 2);
$isHovering = $mouseX >= $rectX && $mouseX <= ($rectX + $rectSize) &&
$mouseY >= $rectY && $mouseY <= ($rectY + $rectSize);
break;
case RGFW_mouseButtonPressed:
if ($isHovering) {
echo "$title - Rectangle clicked!\n";
}
break;
}
}
// Check if window should close
if (rgfw_window_shouldClose($window)) {
$running = false;
}
// Clear with background color
rsgl_clear($window, $r, $g, $b, 255);
// Draw center rectangle
$rectSize = 100;
$rectX = ($width / 2) - ($rectSize / 2);
$rectY = ($height / 2) - ($rectSize / 2);
// White or yellow depending on hover state
if ($isHovering) {
rsgl_setColor($window, 255, 255, 100, 255); // Yellow on hover
} else {
rsgl_setColor($window, 255, 255, 255, 255); // White
}
rsgl_drawRectF($window, (int) $rectX, (int) $rectY, $rectSize, $rectSize);
// Draw text showing frame count (if possible)
$frameCount++;
// Render and swap buffers
rsgl_render($window);
rgfw_window_swapBuffers($window);
// ~60 FPS
usleep(16666);
}
// Cleanup
rsgl_close($window);
rgfw_window_close($window);
return "$title closed after $frameCount frames";
};
try {
// Create first window in a thread (Red background)
echo "Launching Window 1 (Red) in thread...\n";
$runtime1 = new Runtime();
$future1 = $runtime1->run($windowFunction, [
'Window 1 - Red',
100,
100,
400,
300,
[255, 100, 100]
]);
// Create second window in a thread (Blue background)
echo "Launching Window 2 (Blue) in thread...\n";
$runtime2 = new Runtime();
$future2 = $runtime2->run($windowFunction, [
'Window 2 - Blue',
550,
100,
400,
300,
[100, 100, 255]
]);
echo "\nBoth windows launched!\n";
echo "Hover over the center rectangles to see them change color\n";
echo "Click on them to see messages in the console\n";
echo "Main thread waiting for windows to close...\n\n";
// Wait for first window
echo "Waiting for Window 1...\n";
$result1 = $future1->value();
echo $result1 . "\n";
// Wait for second window
echo "Waiting for Window 2...\n";
$result2 = $future2->value();
echo $result2 . "\n";
echo "\nAll windows closed. Application exiting.\n";
} catch (\Throwable $e) {
echo "Error: " . $e->getMessage() . "\n";
echo "Stack trace:\n" . $e->getTraceAsString() . "\n";
}

BIN
php-sdl3/.libs/helper.o Normal file

Binary file not shown.

1
php-sdl3/.libs/sdl3.la Symbolic link
View File

@ -0,0 +1 @@
../sdl3.la

35
php-sdl3/.libs/sdl3.lai Normal file
View File

@ -0,0 +1,35 @@
# sdl3.la - a libtool library file
# Generated by ltmain.sh - GNU libtool 1.5.26 (1.1220.2.492 2008/01/30 06:40:56)
#
# Please DO NOT delete this file!
# It is necessary for linking the library.
# The name that we can dlopen(3).
dlname='sdl3.so'
# Names of this library.
library_names='sdl3.so sdl3.so sdl3.so'
# The name of the static archive.
old_library=''
# Libraries that this one depends upon.
dependency_libs=' -L/usr/local/lib -lSDL3_gfx -lSDL3'
# Version information for sdl3.
current=0
age=0
revision=0
# Is this an already installed library?
installed=yes
# Should we warn about portability when linking against -modules?
shouldnotlink=yes
# Files to dlopen/dlpreopen
dlopen=''
dlpreopen=''
# Directory that this library needs to be installed in:
libdir='/home/thomas/projekte/phpnative/framework/php-sdl3/modules'

BIN
php-sdl3/.libs/sdl3.o Normal file

Binary file not shown.

BIN
php-sdl3/.libs/sdl3.so Executable file

Binary file not shown.

216
php-sdl3/Makefile Normal file
View File

@ -0,0 +1,216 @@
srcdir = /home/thomas/projekte/phpnative/framework/php-sdl3
builddir = /home/thomas/projekte/phpnative/framework/php-sdl3
top_srcdir = /home/thomas/projekte/phpnative/framework/php-sdl3
top_builddir = /home/thomas/projekte/phpnative/framework/php-sdl3
EGREP = /usr/bin/grep -E
SED = /usr/bin/sed
AWK = nawk
SHLIB_SUFFIX_NAME = so
SHLIB_DL_SUFFIX_NAME = so
shared_objects_sdl3 = sdl3.lo helper.lo
PHP_PECL_EXTENSION = sdl3
PHP_MODULES = $(phplibdir)/sdl3.la
PHP_ZEND_EX =
all_targets = $(PHP_MODULES) $(PHP_ZEND_EX)
install_targets = install-modules install-headers
prefix = /usr/local
exec_prefix = $(prefix)
libdir = ${exec_prefix}/lib
phpincludedir = /usr/local/include/php
CC = cc
CFLAGS = -g -O2 -I/usr/include/pipewire-0.3 -I/usr/include/spa-0.2 -D_REENTRANT -I/usr/include/libdrm -I/usr/include/libdecor-0 -I/usr/local/include -I/usr/include/pipewire-0.3 -I/usr/include/spa-0.2 -D_REENTRANT -I/usr/include/libdrm -I/usr/include/libdecor-0
CFLAGS_CLEAN = $(CFLAGS) -D_GNU_SOURCE
CPP = cc -E
CPPFLAGS = -DHAVE_CONFIG_H
CXX =
CXXFLAGS =
CXXFLAGS_CLEAN = $(CXXFLAGS)
EXTENSION_DIR = /usr/local/lib/php/extensions/no-debug-zts-20240924
PHP_EXECUTABLE = /usr/local/bin/php
EXTRA_LDFLAGS =
EXTRA_LIBS =
INCLUDES = -I/usr/local/include/php -I/usr/local/include/php/main -I/usr/local/include/php/TSRM -I/usr/local/include/php/Zend -I/usr/local/include/php/ext -I/usr/local/include/php/ext/date/lib
LDFLAGS = -lSDL3 -L/usr/local/lib -lSDL3_gfx -lSDL3
LIBTOOL = $(SHELL) $(top_builddir)/libtool
SHELL = /bin/bash
INSTALL_HEADERS =
BUILD_CC = cc
phplibdir = /home/thomas/projekte/phpnative/framework/php-sdl3/modules
mkinstalldirs = $(top_srcdir)/build/shtool mkdir -p
INSTALL = $(top_srcdir)/build/shtool install -c
INSTALL_DATA = $(INSTALL) -m 644
COMMON_FLAGS = $(INCLUDES) $(EXTRA_INCLUDES) $(CPPFLAGS) $(PHP_FRAMEWORKPATH)
all: $(all_targets)
@echo
@echo "Build complete."
@echo "Don't forget to run 'make test'."
@echo
build-modules: $(PHP_MODULES) $(PHP_ZEND_EX)
build-binaries: $(PHP_BINARIES)
libphp.la: $(PHP_GLOBAL_OBJS) $(PHP_SAPI_OBJS)
$(LIBTOOL) --tag=CC --mode=link $(CC) $(LIBPHP_CFLAGS) $(CFLAGS) $(EXTRA_CFLAGS) -rpath $(phptempdir) $(EXTRA_LDFLAGS) $(LDFLAGS) $(PHP_RPATHS) $(PHP_GLOBAL_OBJS) $(PHP_SAPI_OBJS) $(EXTRA_LIBS) $(ZEND_EXTRA_LIBS) -o $@
-@$(LIBTOOL) --tag=CC --mode=install cp $@ $(phptempdir)/$@ >/dev/null 2>&1
libphp.dylib: libphp.la
$(LIBTOOL) --tag=CC --mode=link $(CC) -dynamiclib $(LIBPHP_CFLAGS) $(CFLAGS_CLEAN) $(EXTRA_CFLAGS) -rpath $(phptempdir) -install_name @rpath/$@ $(EXTRA_LDFLAGS) $(LDFLAGS) $(PHP_RPATHS) $(PHP_GLOBAL_OBJS) $(PHP_SAPI_OBJS) $(EXTRA_LIBS) $(ZEND_EXTRA_LIBS) -o $@
-@$(LIBTOOL) --silent --tag=CC --mode=install cp $@ $(phptempdir)/$@ >/dev/null 2>&1
libs/libphp.bundle: $(PHP_GLOBAL_OBJS) $(PHP_SAPI_OBJS)
$(CC) $(MH_BUNDLE_FLAGS) $(CFLAGS_CLEAN) $(EXTRA_CFLAGS) $(LDFLAGS) $(EXTRA_LDFLAGS) $(PHP_GLOBAL_OBJS:.lo=.o) $(PHP_SAPI_OBJS:.lo=.o) $(PHP_FRAMEWORKS) $(EXTRA_LIBS) $(ZEND_EXTRA_LIBS) -o $@ && cp $@ libs/libphp.so
install: $(all_targets) $(install_targets)
install-sapi: $(OVERALL_TARGET)
@echo "Installing PHP SAPI module: $(PHP_SAPI)"
-@$(mkinstalldirs) $(INSTALL_ROOT)$(bindir)
-@if test ! -r $(phptempdir)/libphp.$(SHLIB_DL_SUFFIX_NAME); then \
for i in 0.0.0 0.0 0; do \
if test -r $(phptempdir)/libphp.$(SHLIB_DL_SUFFIX_NAME).$$i; then \
$(LN_S) $(phptempdir)/libphp.$(SHLIB_DL_SUFFIX_NAME).$$i $(phptempdir)/libphp.$(SHLIB_DL_SUFFIX_NAME); \
break; \
fi; \
done; \
fi
@$(INSTALL_IT)
install-binaries: build-binaries $(install_binary_targets)
install-modules: build-modules
@test -d modules && \
$(mkinstalldirs) $(INSTALL_ROOT)$(EXTENSION_DIR)
@echo "Installing shared extensions: $(INSTALL_ROOT)$(EXTENSION_DIR)/"
@rm -f modules/*.la >/dev/null 2>&1
@$(INSTALL) modules/* $(INSTALL_ROOT)$(EXTENSION_DIR)
install-headers:
-@if test "$(INSTALL_HEADERS)"; then \
for i in `echo $(INSTALL_HEADERS)`; do \
i=`$(top_srcdir)/build/shtool path -d $$i`; \
paths="$$paths $(INSTALL_ROOT)$(phpincludedir)/$$i"; \
done; \
$(mkinstalldirs) $$paths && \
echo "Installing header files: $(INSTALL_ROOT)$(phpincludedir)/" && \
for i in `echo $(INSTALL_HEADERS)`; do \
if test "$(PHP_PECL_EXTENSION)"; then \
src=`echo $$i | $(SED) -e "s#ext/$(PHP_PECL_EXTENSION)/##g"`; \
else \
src=$$i; \
fi; \
if test -f "$(top_srcdir)/$$src"; then \
$(INSTALL_DATA) $(top_srcdir)/$$src $(INSTALL_ROOT)$(phpincludedir)/$$i; \
elif test -f "$(top_builddir)/$$src"; then \
$(INSTALL_DATA) $(top_builddir)/$$src $(INSTALL_ROOT)$(phpincludedir)/$$i; \
else \
(cd $(top_srcdir)/$$src && $(INSTALL_DATA) *.h $(INSTALL_ROOT)$(phpincludedir)/$$i; \
cd $(top_builddir)/$$src && $(INSTALL_DATA) *.h $(INSTALL_ROOT)$(phpincludedir)/$$i) 2>/dev/null || true; \
fi \
done; \
fi
PHP_TEST_SETTINGS = -d 'open_basedir=' -d 'output_buffering=0' -d 'memory_limit=-1'
PHP_TEST_SHARED_EXTENSIONS = ` \
if test "x$(PHP_MODULES)" != "x"; then \
for i in $(PHP_MODULES)""; do \
. $$i; \
if test "x$$dlname" != "xdl_test.so"; then \
$(top_srcdir)/build/shtool echo -n -- " -d extension=$$dlname"; \
fi; \
done; \
fi; \
if test "x$(PHP_ZEND_EX)" != "x"; then \
for i in $(PHP_ZEND_EX)""; do \
. $$i; $(top_srcdir)/build/shtool echo -n -- " -d zend_extension=$(top_builddir)/modules/$$dlname"; \
done; \
fi`
PHP_DEPRECATED_DIRECTIVES_REGEX = '^[\t\ ]*(magic_quotes_(gpc|runtime|sybase)?|(zend_)?extension(_debug)?(_ts)?|session\.sid_(length|bits_per_character))[\t\ ]*='
test: all
@if test ! -z "$(PHP_EXECUTABLE)" && test -x "$(PHP_EXECUTABLE)"; then \
INI_FILE=`$(PHP_EXECUTABLE) -d 'display_errors=stderr' -r 'echo php_ini_loaded_file();' 2> /dev/null`; \
if test "$$INI_FILE"; then \
$(EGREP) -h -v $(PHP_DEPRECATED_DIRECTIVES_REGEX) "$$INI_FILE" > $(top_builddir)/tmp-php.ini; \
else \
echo > $(top_builddir)/tmp-php.ini; \
fi; \
INI_SCANNED_PATH=`$(PHP_EXECUTABLE) -d 'display_errors=stderr' -r '$$a = explode(",\n", trim(php_ini_scanned_files())); echo $$a[0];' 2> /dev/null`; \
if test "$$INI_SCANNED_PATH"; then \
INI_SCANNED_PATH=`$(top_srcdir)/build/shtool path -d $$INI_SCANNED_PATH`; \
$(EGREP) -h -v $(PHP_DEPRECATED_DIRECTIVES_REGEX) "$$INI_SCANNED_PATH"/*.ini >> $(top_builddir)/tmp-php.ini; \
fi; \
TEST_PHP_EXECUTABLE=$(PHP_EXECUTABLE) \
TEST_PHP_SRCDIR=$(top_srcdir) \
CC="$(CC)" \
$(PHP_EXECUTABLE) -n -c $(top_builddir)/tmp-php.ini $(PHP_TEST_SETTINGS) $(top_srcdir)/run-tests.php -n -c $(top_builddir)/tmp-php.ini -d extension_dir=$(top_builddir)/modules/ $(PHP_TEST_SHARED_EXTENSIONS) $(TESTS); \
TEST_RESULT_EXIT_CODE=$$?; \
rm $(top_builddir)/tmp-php.ini; \
exit $$TEST_RESULT_EXIT_CODE; \
else \
echo "ERROR: Cannot run tests without CLI sapi."; \
fi
clean:
find . -name \*.gcno -o -name \*.gcda | xargs rm -f
find . -name \*.lo -o -name \*.o -o -name \*.dep | xargs rm -f
find . -name \*.la -o -name \*.a | xargs rm -f
find . -name \*.so | xargs rm -f
find . -name .libs -a -type d|xargs rm -rf
rm -f libphp.la $(SAPI_CLI_PATH) $(SAPI_CGI_PATH) $(SAPI_LITESPEED_PATH) $(SAPI_FPM_PATH) $(OVERALL_TARGET) modules/* libs/*
rm -f ext/opcache/jit/ir/gen_ir_fold_hash
rm -f ext/opcache/jit/ir/minilua
rm -f ext/opcache/jit/ir/ir_fold_hash.h
rm -f ext/opcache/jit/ir/ir_emit_x86.h
rm -f ext/opcache/jit/ir/ir_emit_aarch64.h
distclean: clean
rm -f Makefile config.cache config.log config.status Makefile.objects Makefile.fragments libtool main/php_config.h main/internal_functions_cli.c main/internal_functions.c Zend/zend_dtrace_gen.h Zend/zend_dtrace_gen.h.bak Zend/zend_config.h
rm -f main/build-defs.h scripts/phpize
rm -f ext/date/lib/timelib_config.h ext/mbstring/libmbfl/config.h
rm -f scripts/man1/phpize.1 scripts/php-config scripts/man1/php-config.1 sapi/cli/php.1 sapi/cgi/php-cgi.1 sapi/phpdbg/phpdbg.1 ext/phar/phar.1 ext/phar/phar.phar.1
rm -f sapi/fpm/php-fpm.conf sapi/fpm/init.d.php-fpm sapi/fpm/php-fpm.service sapi/fpm/php-fpm.8 sapi/fpm/status.html
rm -f ext/phar/phar.phar ext/phar/phar.php
if test "$(srcdir)" != "$(builddir)"; then \
rm -f ext/phar/phar/phar.inc; \
fi
prof-gen:
CCACHE_DISABLE=1 $(MAKE) PROF_FLAGS=-fprofile-generate all
find . -name \*.gcda | xargs rm -f
prof-clean:
find . -name \*.lo -o -name \*.o | xargs rm -f
find . -name \*.la -o -name \*.a | xargs rm -f
find . -name \*.so | xargs rm -f
rm -f libphp.la $(SAPI_CLI_PATH) $(SAPI_CGI_PATH) $(SAPI_LITESPEED_PATH) $(SAPI_FPM_PATH) $(OVERALL_TARGET) modules/* libs/*
prof-use:
CCACHE_DISABLE=1 $(MAKE) PROF_FLAGS=-fprofile-use all
%_arginfo.h: %.stub.php
@if test -e "$(top_srcdir)/build/gen_stub.php"; then \
if test ! -z "$(PHP)"; then \
echo Parse $< to generate $@;\
$(PHP) $(top_srcdir)/build/gen_stub.php $<; \
elif test ! -z "$(PHP_EXECUTABLE)" && test -x "$(PHP_EXECUTABLE)"; then \
echo Parse $< to generate $@;\
$(PHP_EXECUTABLE) $(top_srcdir)/build/gen_stub.php $<; \
fi; \
fi;
.PHONY: all clean install distclean test prof-gen prof-clean prof-use
-include sdl3.dep
sdl3.lo: /home/thomas/projekte/phpnative/framework/php-sdl3/sdl3.c
$(LIBTOOL) --tag=CC --mode=compile $(CC) -I. -I/home/thomas/projekte/phpnative/framework/php-sdl3 $(COMMON_FLAGS) $(CFLAGS_CLEAN) $(EXTRA_CFLAGS) -DZEND_COMPILE_DL_EXT=1 -c /home/thomas/projekte/phpnative/framework/php-sdl3/sdl3.c -o sdl3.lo -MMD -MF sdl3.dep -MT sdl3.lo
-include helper.dep
helper.lo: /home/thomas/projekte/phpnative/framework/php-sdl3/helper.c
$(LIBTOOL) --tag=CC --mode=compile $(CC) -I. -I/home/thomas/projekte/phpnative/framework/php-sdl3 $(COMMON_FLAGS) $(CFLAGS_CLEAN) $(EXTRA_CFLAGS) -DZEND_COMPILE_DL_EXT=1 -c /home/thomas/projekte/phpnative/framework/php-sdl3/helper.c -o helper.lo -MMD -MF helper.dep -MT helper.lo
$(phplibdir)/sdl3.la: ./sdl3.la
$(LIBTOOL) --tag=CC --mode=install cp ./sdl3.la $(phplibdir)
./sdl3.la: $(shared_objects_sdl3) $(SDL3_SHARED_DEPENDENCIES)
$(LIBTOOL) --tag=CC --mode=link $(CC) -shared $(COMMON_FLAGS) $(CFLAGS_CLEAN) $(EXTRA_CFLAGS) $(LDFLAGS) -o $@ -export-dynamic -avoid-version -prefer-pic -module -rpath $(phplibdir) $(EXTRA_LDFLAGS) $(shared_objects_sdl3) $(SDL3_SHARED_LIBADD)

View File

12
php-sdl3/Makefile.objects Normal file
View File

@ -0,0 +1,12 @@
-include sdl3.dep
sdl3.lo: /home/thomas/projekte/phpnative/framework/php-sdl3/sdl3.c
$(LIBTOOL) --tag=CC --mode=compile $(CC) -I. -I/home/thomas/projekte/phpnative/framework/php-sdl3 $(COMMON_FLAGS) $(CFLAGS_CLEAN) $(EXTRA_CFLAGS) -DZEND_COMPILE_DL_EXT=1 -c /home/thomas/projekte/phpnative/framework/php-sdl3/sdl3.c -o sdl3.lo -MMD -MF sdl3.dep -MT sdl3.lo
-include helper.dep
helper.lo: /home/thomas/projekte/phpnative/framework/php-sdl3/helper.c
$(LIBTOOL) --tag=CC --mode=compile $(CC) -I. -I/home/thomas/projekte/phpnative/framework/php-sdl3 $(COMMON_FLAGS) $(CFLAGS_CLEAN) $(EXTRA_CFLAGS) -DZEND_COMPILE_DL_EXT=1 -c /home/thomas/projekte/phpnative/framework/php-sdl3/helper.c -o helper.lo -MMD -MF helper.dep -MT helper.lo
$(phplibdir)/sdl3.la: ./sdl3.la
$(LIBTOOL) --tag=CC --mode=install cp ./sdl3.la $(phplibdir)
./sdl3.la: $(shared_objects_sdl3) $(SDL3_SHARED_DEPENDENCIES)
$(LIBTOOL) --tag=CC --mode=link $(CC) -shared $(COMMON_FLAGS) $(CFLAGS_CLEAN) $(EXTRA_CFLAGS) $(LDFLAGS) -o $@ -export-dynamic -avoid-version -prefer-pic -module -rpath $(phplibdir) $(EXTRA_LDFLAGS) $(shared_objects_sdl3) $(SDL3_SHARED_LIBADD)

View File

@ -0,0 +1,166 @@
mkinstalldirs = $(top_srcdir)/build/shtool mkdir -p
INSTALL = $(top_srcdir)/build/shtool install -c
INSTALL_DATA = $(INSTALL) -m 644
COMMON_FLAGS = $(INCLUDES) $(EXTRA_INCLUDES) $(CPPFLAGS) $(PHP_FRAMEWORKPATH)
all: $(all_targets)
@echo
@echo "Build complete."
@echo "Don't forget to run 'make test'."
@echo
build-modules: $(PHP_MODULES) $(PHP_ZEND_EX)
build-binaries: $(PHP_BINARIES)
libphp.la: $(PHP_GLOBAL_OBJS) $(PHP_SAPI_OBJS)
$(LIBTOOL) --tag=CC --mode=link $(CC) $(LIBPHP_CFLAGS) $(CFLAGS) $(EXTRA_CFLAGS) -rpath $(phptempdir) $(EXTRA_LDFLAGS) $(LDFLAGS) $(PHP_RPATHS) $(PHP_GLOBAL_OBJS) $(PHP_SAPI_OBJS) $(EXTRA_LIBS) $(ZEND_EXTRA_LIBS) -o $@
-@$(LIBTOOL) --tag=CC --mode=install cp $@ $(phptempdir)/$@ >/dev/null 2>&1
libphp.dylib: libphp.la
$(LIBTOOL) --tag=CC --mode=link $(CC) -dynamiclib $(LIBPHP_CFLAGS) $(CFLAGS_CLEAN) $(EXTRA_CFLAGS) -rpath $(phptempdir) -install_name @rpath/$@ $(EXTRA_LDFLAGS) $(LDFLAGS) $(PHP_RPATHS) $(PHP_GLOBAL_OBJS) $(PHP_SAPI_OBJS) $(EXTRA_LIBS) $(ZEND_EXTRA_LIBS) -o $@
-@$(LIBTOOL) --silent --tag=CC --mode=install cp $@ $(phptempdir)/$@ >/dev/null 2>&1
libs/libphp.bundle: $(PHP_GLOBAL_OBJS) $(PHP_SAPI_OBJS)
$(CC) $(MH_BUNDLE_FLAGS) $(CFLAGS_CLEAN) $(EXTRA_CFLAGS) $(LDFLAGS) $(EXTRA_LDFLAGS) $(PHP_GLOBAL_OBJS:.lo=.o) $(PHP_SAPI_OBJS:.lo=.o) $(PHP_FRAMEWORKS) $(EXTRA_LIBS) $(ZEND_EXTRA_LIBS) -o $@ && cp $@ libs/libphp.so
install: $(all_targets) $(install_targets)
install-sapi: $(OVERALL_TARGET)
@echo "Installing PHP SAPI module: $(PHP_SAPI)"
-@$(mkinstalldirs) $(INSTALL_ROOT)$(bindir)
-@if test ! -r $(phptempdir)/libphp.$(SHLIB_DL_SUFFIX_NAME); then \
for i in 0.0.0 0.0 0; do \
if test -r $(phptempdir)/libphp.$(SHLIB_DL_SUFFIX_NAME).$$i; then \
$(LN_S) $(phptempdir)/libphp.$(SHLIB_DL_SUFFIX_NAME).$$i $(phptempdir)/libphp.$(SHLIB_DL_SUFFIX_NAME); \
break; \
fi; \
done; \
fi
@$(INSTALL_IT)
install-binaries: build-binaries $(install_binary_targets)
install-modules: build-modules
@test -d modules && \
$(mkinstalldirs) $(INSTALL_ROOT)$(EXTENSION_DIR)
@echo "Installing shared extensions: $(INSTALL_ROOT)$(EXTENSION_DIR)/"
@rm -f modules/*.la >/dev/null 2>&1
@$(INSTALL) modules/* $(INSTALL_ROOT)$(EXTENSION_DIR)
install-headers:
-@if test "$(INSTALL_HEADERS)"; then \
for i in `echo $(INSTALL_HEADERS)`; do \
i=`$(top_srcdir)/build/shtool path -d $$i`; \
paths="$$paths $(INSTALL_ROOT)$(phpincludedir)/$$i"; \
done; \
$(mkinstalldirs) $$paths && \
echo "Installing header files: $(INSTALL_ROOT)$(phpincludedir)/" && \
for i in `echo $(INSTALL_HEADERS)`; do \
if test "$(PHP_PECL_EXTENSION)"; then \
src=`echo $$i | $(SED) -e "s#ext/$(PHP_PECL_EXTENSION)/##g"`; \
else \
src=$$i; \
fi; \
if test -f "$(top_srcdir)/$$src"; then \
$(INSTALL_DATA) $(top_srcdir)/$$src $(INSTALL_ROOT)$(phpincludedir)/$$i; \
elif test -f "$(top_builddir)/$$src"; then \
$(INSTALL_DATA) $(top_builddir)/$$src $(INSTALL_ROOT)$(phpincludedir)/$$i; \
else \
(cd $(top_srcdir)/$$src && $(INSTALL_DATA) *.h $(INSTALL_ROOT)$(phpincludedir)/$$i; \
cd $(top_builddir)/$$src && $(INSTALL_DATA) *.h $(INSTALL_ROOT)$(phpincludedir)/$$i) 2>/dev/null || true; \
fi \
done; \
fi
PHP_TEST_SETTINGS = -d 'open_basedir=' -d 'output_buffering=0' -d 'memory_limit=-1'
PHP_TEST_SHARED_EXTENSIONS = ` \
if test "x$(PHP_MODULES)" != "x"; then \
for i in $(PHP_MODULES)""; do \
. $$i; \
if test "x$$dlname" != "xdl_test.so"; then \
$(top_srcdir)/build/shtool echo -n -- " -d extension=$$dlname"; \
fi; \
done; \
fi; \
if test "x$(PHP_ZEND_EX)" != "x"; then \
for i in $(PHP_ZEND_EX)""; do \
. $$i; $(top_srcdir)/build/shtool echo -n -- " -d zend_extension=$(top_builddir)/modules/$$dlname"; \
done; \
fi`
PHP_DEPRECATED_DIRECTIVES_REGEX = '^[\t\ ]*(magic_quotes_(gpc|runtime|sybase)?|(zend_)?extension(_debug)?(_ts)?|session\.sid_(length|bits_per_character))[\t\ ]*='
test: all
@if test ! -z "$(PHP_EXECUTABLE)" && test -x "$(PHP_EXECUTABLE)"; then \
INI_FILE=`$(PHP_EXECUTABLE) -d 'display_errors=stderr' -r 'echo php_ini_loaded_file();' 2> /dev/null`; \
if test "$$INI_FILE"; then \
$(EGREP) -h -v $(PHP_DEPRECATED_DIRECTIVES_REGEX) "$$INI_FILE" > $(top_builddir)/tmp-php.ini; \
else \
echo > $(top_builddir)/tmp-php.ini; \
fi; \
INI_SCANNED_PATH=`$(PHP_EXECUTABLE) -d 'display_errors=stderr' -r '$$a = explode(",\n", trim(php_ini_scanned_files())); echo $$a[0];' 2> /dev/null`; \
if test "$$INI_SCANNED_PATH"; then \
INI_SCANNED_PATH=`$(top_srcdir)/build/shtool path -d $$INI_SCANNED_PATH`; \
$(EGREP) -h -v $(PHP_DEPRECATED_DIRECTIVES_REGEX) "$$INI_SCANNED_PATH"/*.ini >> $(top_builddir)/tmp-php.ini; \
fi; \
TEST_PHP_EXECUTABLE=$(PHP_EXECUTABLE) \
TEST_PHP_SRCDIR=$(top_srcdir) \
CC="$(CC)" \
$(PHP_EXECUTABLE) -n -c $(top_builddir)/tmp-php.ini $(PHP_TEST_SETTINGS) $(top_srcdir)/run-tests.php -n -c $(top_builddir)/tmp-php.ini -d extension_dir=$(top_builddir)/modules/ $(PHP_TEST_SHARED_EXTENSIONS) $(TESTS); \
TEST_RESULT_EXIT_CODE=$$?; \
rm $(top_builddir)/tmp-php.ini; \
exit $$TEST_RESULT_EXIT_CODE; \
else \
echo "ERROR: Cannot run tests without CLI sapi."; \
fi
clean:
find . -name \*.gcno -o -name \*.gcda | xargs rm -f
find . -name \*.lo -o -name \*.o -o -name \*.dep | xargs rm -f
find . -name \*.la -o -name \*.a | xargs rm -f
find . -name \*.so | xargs rm -f
find . -name .libs -a -type d|xargs rm -rf
rm -f libphp.la $(SAPI_CLI_PATH) $(SAPI_CGI_PATH) $(SAPI_LITESPEED_PATH) $(SAPI_FPM_PATH) $(OVERALL_TARGET) modules/* libs/*
rm -f ext/opcache/jit/ir/gen_ir_fold_hash
rm -f ext/opcache/jit/ir/minilua
rm -f ext/opcache/jit/ir/ir_fold_hash.h
rm -f ext/opcache/jit/ir/ir_emit_x86.h
rm -f ext/opcache/jit/ir/ir_emit_aarch64.h
distclean: clean
rm -f Makefile config.cache config.log config.status Makefile.objects Makefile.fragments libtool main/php_config.h main/internal_functions_cli.c main/internal_functions.c Zend/zend_dtrace_gen.h Zend/zend_dtrace_gen.h.bak Zend/zend_config.h
rm -f main/build-defs.h scripts/phpize
rm -f ext/date/lib/timelib_config.h ext/mbstring/libmbfl/config.h
rm -f scripts/man1/phpize.1 scripts/php-config scripts/man1/php-config.1 sapi/cli/php.1 sapi/cgi/php-cgi.1 sapi/phpdbg/phpdbg.1 ext/phar/phar.1 ext/phar/phar.phar.1
rm -f sapi/fpm/php-fpm.conf sapi/fpm/init.d.php-fpm sapi/fpm/php-fpm.service sapi/fpm/php-fpm.8 sapi/fpm/status.html
rm -f ext/phar/phar.phar ext/phar/phar.php
if test "$(srcdir)" != "$(builddir)"; then \
rm -f ext/phar/phar/phar.inc; \
fi
prof-gen:
CCACHE_DISABLE=1 $(MAKE) PROF_FLAGS=-fprofile-generate all
find . -name \*.gcda | xargs rm -f
prof-clean:
find . -name \*.lo -o -name \*.o | xargs rm -f
find . -name \*.la -o -name \*.a | xargs rm -f
find . -name \*.so | xargs rm -f
rm -f libphp.la $(SAPI_CLI_PATH) $(SAPI_CGI_PATH) $(SAPI_LITESPEED_PATH) $(SAPI_FPM_PATH) $(OVERALL_TARGET) modules/* libs/*
prof-use:
CCACHE_DISABLE=1 $(MAKE) PROF_FLAGS=-fprofile-use all
%_arginfo.h: %.stub.php
@if test -e "$(top_srcdir)/build/gen_stub.php"; then \
if test ! -z "$(PHP)"; then \
echo Parse $< to generate $@;\
$(PHP) $(top_srcdir)/build/gen_stub.php $<; \
elif test ! -z "$(PHP_EXECUTABLE)" && test -x "$(PHP_EXECUTABLE)"; then \
echo Parse $< to generate $@;\
$(PHP_EXECUTABLE) $(top_srcdir)/build/gen_stub.php $<; \
fi; \
fi;
.PHONY: all clean install distclean test prof-gen prof-clean prof-use

View File

@ -0,0 +1,53 @@
# ===========================================================================
# https://www.gnu.org/software/autoconf-archive/ax_check_compile_flag.html
# ===========================================================================
#
# SYNOPSIS
#
# AX_CHECK_COMPILE_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS], [INPUT])
#
# DESCRIPTION
#
# Check whether the given FLAG works with the current language's compiler
# or gives an error. (Warnings, however, are ignored)
#
# ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on
# success/failure.
#
# If EXTRA-FLAGS is defined, it is added to the current language's default
# flags (e.g. CFLAGS) when the check is done. The check is thus made with
# the flags: "CFLAGS EXTRA-FLAGS FLAG". This can for example be used to
# force the compiler to issue an error when a bad flag is given.
#
# INPUT gives an alternative input source to AC_COMPILE_IFELSE.
#
# NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this
# macro in sync with AX_CHECK_{PREPROC,LINK}_FLAG.
#
# LICENSE
#
# Copyright (c) 2008 Guido U. Draheim <guidod@gmx.de>
# Copyright (c) 2011 Maarten Bosmans <mkbosmans@gmail.com>
#
# Copying and distribution of this file, with or without modification, are
# permitted in any medium without royalty provided the copyright notice
# and this notice are preserved. This file is offered as-is, without any
# warranty.
#serial 7
AC_DEFUN([AX_CHECK_COMPILE_FLAG],
[AC_PREREQ(2.64)dnl for _AC_LANG_PREFIX and AS_VAR_IF
AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_[]_AC_LANG_ABBREV[]flags_$4_$1])dnl
AC_CACHE_CHECK([whether the _AC_LANG compiler accepts $1], CACHEVAR, [
ax_check_save_flags=$[]_AC_LANG_PREFIX[]FLAGS
_AC_LANG_PREFIX[]FLAGS="$[]_AC_LANG_PREFIX[]FLAGS $4 $1"
AC_COMPILE_IFELSE([m4_default([$5],[AC_LANG_PROGRAM()])],
[AS_VAR_SET(CACHEVAR,[yes])],
[AS_VAR_SET(CACHEVAR,[no])])
_AC_LANG_PREFIX[]FLAGS=$ax_check_save_flags])
AS_VAR_IF(CACHEVAR,yes,
[m4_default([$2], :)],
[m4_default([$3], :)])
AS_VAR_POPDEF([CACHEVAR])dnl
])dnl AX_CHECK_COMPILE_FLAGS

View File

@ -0,0 +1,241 @@
# ===========================================================================
# https://www.gnu.org/software/autoconf-archive/ax_gcc_func_attribute.html
# ===========================================================================
#
# SYNOPSIS
#
# AX_GCC_FUNC_ATTRIBUTE(ATTRIBUTE)
#
# DESCRIPTION
#
# This macro checks if the compiler supports one of GCC's function
# attributes; many other compilers also provide function attributes with
# the same syntax. Compiler warnings are used to detect supported
# attributes as unsupported ones are ignored by default so quieting
# warnings when using this macro will yield false positives.
#
# The ATTRIBUTE parameter holds the name of the attribute to be checked.
#
# If ATTRIBUTE is supported define HAVE_FUNC_ATTRIBUTE_<ATTRIBUTE>.
#
# The macro caches its result in the ax_cv_have_func_attribute_<attribute>
# variable.
#
# The macro currently supports the following function attributes:
#
# alias
# aligned
# alloc_size
# always_inline
# artificial
# cold
# const
# constructor
# constructor_priority for constructor attribute with priority
# deprecated
# destructor
# dllexport
# dllimport
# error
# externally_visible
# fallthrough
# flatten
# format
# format_arg
# gnu_inline
# hot
# ifunc
# leaf
# malloc
# noclone
# noinline
# nonnull
# noreturn
# nothrow
# optimize
# pure
# sentinel
# sentinel_position
# unused
# used
# visibility
# warning
# warn_unused_result
# weak
# weakref
#
# Unsupported function attributes will be tested with a prototype
# returning an int and not accepting any arguments and the result of the
# check might be wrong or meaningless so use with care.
#
# LICENSE
#
# Copyright (c) 2013 Gabriele Svelto <gabriele.svelto@gmail.com>
#
# Copying and distribution of this file, with or without modification, are
# permitted in any medium without royalty provided the copyright notice
# and this notice are preserved. This file is offered as-is, without any
# warranty.
#serial 9
AC_DEFUN([AX_GCC_FUNC_ATTRIBUTE], [
AS_VAR_PUSHDEF([ac_var], [ax_cv_have_func_attribute_$1])
AC_CACHE_CHECK([for __attribute__(($1))], [ac_var], [
AC_LINK_IFELSE([AC_LANG_PROGRAM([
m4_case([$1],
[alias], [
int foo( void ) { return 0; }
int bar( void ) __attribute__(($1("foo")));
],
[aligned], [
int foo( void ) __attribute__(($1(32)));
],
[alloc_size], [
void *foo(int a) __attribute__(($1(1)));
],
[always_inline], [
inline __attribute__(($1)) int foo( void ) { return 0; }
],
[artificial], [
inline __attribute__(($1)) int foo( void ) { return 0; }
],
[cold], [
int foo( void ) __attribute__(($1));
],
[const], [
int foo( void ) __attribute__(($1));
],
[constructor_priority], [
int foo( void ) __attribute__((__constructor__(65535/2)));
],
[constructor], [
int foo( void ) __attribute__(($1));
],
[deprecated], [
int foo( void ) __attribute__(($1("")));
],
[destructor], [
int foo( void ) __attribute__(($1));
],
[dllexport], [
__attribute__(($1)) int foo( void ) { return 0; }
],
[dllimport], [
int foo( void ) __attribute__(($1));
],
[error], [
int foo( void ) __attribute__(($1("")));
],
[externally_visible], [
int foo( void ) __attribute__(($1));
],
[fallthrough], [
int foo( void ) {switch (0) { case 1: __attribute__(($1)); case 2: break ; }};
],
[flatten], [
int foo( void ) __attribute__(($1));
],
[format], [
int foo(const char *p, ...) __attribute__(($1(printf, 1, 2)));
],
[format_arg], [
char *foo(const char *p) __attribute__(($1(1)));
],
[gnu_inline], [
inline __attribute__(($1)) int foo( void ) { return 0; }
],
[hot], [
int foo( void ) __attribute__(($1));
],
[ifunc], [
int my_foo( void ) { return 0; }
static int (*resolve_foo(void))(void) { return my_foo; }
int foo( void ) __attribute__(($1("resolve_foo")));
],
[leaf], [
__attribute__(($1)) int foo( void ) { return 0; }
],
[malloc], [
void *foo( void ) __attribute__(($1));
],
[noclone], [
int foo( void ) __attribute__(($1));
],
[noinline], [
__attribute__(($1)) int foo( void ) { return 0; }
],
[nonnull], [
int foo(char *p) __attribute__(($1(1)));
],
[noreturn], [
void foo( void ) __attribute__(($1));
],
[nothrow], [
int foo( void ) __attribute__(($1));
],
[optimize], [
__attribute__(($1(3))) int foo( void ) { return 0; }
],
[pure], [
int foo( void ) __attribute__(($1));
],
[sentinel], [
int foo(void *p, ...) __attribute__(($1));
],
[sentinel_position], [
int foo(void *p, ...) __attribute__(($1(1)));
],
[returns_nonnull], [
void *foo( void ) __attribute__(($1));
],
[unused], [
int foo( void ) __attribute__(($1));
],
[used], [
int foo( void ) __attribute__(($1));
],
[visibility], [
int foo_def( void ) __attribute__(($1("default")));
int foo_hid( void ) __attribute__(($1("hidden")));
int foo_int( void ) __attribute__(($1("internal")));
int foo_pro( void ) __attribute__(($1("protected")));
],
[warning], [
int foo( void ) __attribute__(($1("")));
],
[warn_unused_result], [
int foo( void ) __attribute__(($1));
],
[weak], [
int foo( void ) __attribute__(($1));
],
[weakref], [
static int foo( void ) { return 0; }
static int bar( void ) __attribute__(($1("foo")));
],
[target], [
int bar( void ) __attribute__(($1("sse2")));
],
[
m4_warn([syntax], [Unsupported attribute $1, the test may fail])
int foo( void ) __attribute__(($1));
]
)], [])
],
dnl GCC doesn't exit with an error if an unknown attribute is
dnl provided but only outputs a warning, so accept the attribute
dnl only if no warning were issued.
[AS_IF([test -s conftest.err],
[AS_VAR_SET([ac_var], [no])],
[AS_VAR_SET([ac_var], [yes])])],
[AS_VAR_SET([ac_var], [no])])
])
AS_IF([test yes = AS_VAR_GET([ac_var])],
[AC_DEFINE_UNQUOTED(AS_TR_CPP(HAVE_FUNC_ATTRIBUTE_$1), 1,
[Define to 1 if the system has the `$1' function attribute])], [])
AS_VAR_POPDEF([ac_var])
])

1815
php-sdl3/build/config.guess vendored Executable file

File diff suppressed because it is too large Load Diff

2354
php-sdl3/build/config.sub vendored Executable file

File diff suppressed because it is too large Load Diff

6328
php-sdl3/build/gen_stub.php Normal file

File diff suppressed because it is too large Load Diff

6370
php-sdl3/build/libtool.m4 vendored Normal file

File diff suppressed because it is too large Load Diff

6970
php-sdl3/build/ltmain.sh Normal file

File diff suppressed because it is too large Load Diff

2560
php-sdl3/build/php.m4 Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,956 @@
dnl
dnl Based on https://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx.html
dnl Author: Anatol Belski <ab@php.net>
dnl
dnl PHP_CXX_COMPILE_STDCXX(version, mandatory|optional, var_name_to_put_switch_in)
dnl
dnl ARGUMENTS
dnl
dnl first arg - version as 11, 14, 17 or 20
dnl second arg - if mandatory, the configure will fail when no features found.
dnl Optional will make configure silently continue
dnl third arg - a variable name where the corresponding switch would be put. If
dnl the variable is already defined, its contents will be overwritten.
dnl
dnl EXAMPLE
dnl
dnl PHP_CXX_COMPILE_STDCXX(14, mandatory, MY_STDCXX_SWiTCH)
dnl echo $MY_STDCXX_SWITCH
dnl
dnl
dnl PHP specific implementation start.
dnl
AC_DEFUN([PHP_CXX_COMPILE_STDCXX], [dnl
m4_if([$1], [11], [ax_cxx_compile_alternatives="11 0x"],
[$1], [14], [ax_cxx_compile_alternatives="14 1y"],
[$1], [17], [ax_cxx_compile_alternatives="17 1z"],
[$1], [20], [ax_cxx_compile_alternatives="20"],
[m4_fatal([invalid first argument `$1' to PHP_CXX_COMPILE_STDCXX])])[]dnl
m4_if([$2], [], [ax_cxx_compile_cxx$1_required=true],
[$2], [mandatory], [ax_cxx_compile_cxx$1_required=true],
[$2], [optional], [ax_cxx_compile_cxx$1_required=false],
[m4_fatal([invalid third argument `$2' to PHP_CXX_COMPILE_STDCXX])])[]dnl
AC_LANG_PUSH([C++])dnl
ac_success=no
dnl HP's aCC needs +std=c++11 according to:
dnl http://h21007.www2.hp.com/portal/download/files/unprot/aCxx/PDF_Release_Notes/769149-001.pdf
dnl Cray's crayCC needs "-h std=c++11"
for alternative in ${ax_cxx_compile_alternatives}; do
for switch in -std=c++${alternative} +std=c++${alternative} "-h std=c++${alternative}"; do
cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch])
AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch,
$cachevar,
[ac_save_CXX="$CXX"
CXX="$CXX $switch"
AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])],
[eval $cachevar=yes],
[eval $cachevar=no])
CXX="$ac_save_CXX"])
if eval test x\$$cachevar = xyes; then
eval AS_TR_SH([$3])="$switch"
ac_success=yes
break
fi
done
if test x$ac_success = xyes; then
break
fi
done
AC_LANG_POP([C++])
if test x$ax_cxx_compile_cxx$1_required = xtrue; then
if test x$ac_success = xno; then
AC_MSG_ERROR([*** A compiler with support for C++$1 language features is required.])
fi
fi
if test x$ac_success = xno; then
AC_MSG_NOTICE([No compiler with C++$1 support was found])
fi
AC_SUBST(HAVE_CXX$1)
])
dnl
dnl PHP specific implementation end.
dnl The relevant part of the unchanged original implementation is below.
dnl
#
# LICENSE
#
# Copyright (c) 2008 Benjamin Kosnik <bkoz@redhat.com>
# Copyright (c) 2012 Zack Weinberg <zackw@panix.com>
# Copyright (c) 2013 Roy Stogner <roystgnr@ices.utexas.edu>
# Copyright (c) 2014, 2015 Google Inc.; contributed by Alexey Sokolov <sokolov@google.com>
# Copyright (c) 2015 Paul Norman <penorman@mac.com>
# Copyright (c) 2015 Moritz Klammler <moritz@klammler.eu>
# Copyright (c) 2016, 2018 Krzesimir Nowak <qdlacz@gmail.com>
# Copyright (c) 2019 Enji Cooper <yaneurabeya@gmail.com>
# Copyright (c) 2020 Jason Merrill <jason@redhat.com>
# Copyright (c) 2021 Jörn Heusipp <osmanx@problemloesungsmaschine.de>
#
# Copying and distribution of this file, with or without modification, are
# permitted in any medium without royalty provided the copyright notice
# and this notice are preserved. This file is offered as-is, without any
# warranty.
dnl Test body for checking C++11 support
m4_define([_AX_CXX_COMPILE_STDCXX_testbody_11],
_AX_CXX_COMPILE_STDCXX_testbody_new_in_11
)
dnl Test body for checking C++14 support
m4_define([_AX_CXX_COMPILE_STDCXX_testbody_14],
_AX_CXX_COMPILE_STDCXX_testbody_new_in_11
_AX_CXX_COMPILE_STDCXX_testbody_new_in_14
)
dnl Test body for checking C++17 support
m4_define([_AX_CXX_COMPILE_STDCXX_testbody_17],
_AX_CXX_COMPILE_STDCXX_testbody_new_in_11
_AX_CXX_COMPILE_STDCXX_testbody_new_in_14
_AX_CXX_COMPILE_STDCXX_testbody_new_in_17
)
dnl Test body for checking C++20 support
m4_define([_AX_CXX_COMPILE_STDCXX_testbody_20],
_AX_CXX_COMPILE_STDCXX_testbody_new_in_11
_AX_CXX_COMPILE_STDCXX_testbody_new_in_14
_AX_CXX_COMPILE_STDCXX_testbody_new_in_17
_AX_CXX_COMPILE_STDCXX_testbody_new_in_20
)
dnl Tests for new features in C++11
m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_11], [[
// If the compiler admits that it is not ready for C++11, why torture it?
// Hopefully, this will speed up the test.
#ifndef __cplusplus
#error "This is not a C++ compiler"
#elif __cplusplus < 201103L
#error "This is not a C++11 compiler"
#else
namespace cxx11
{
namespace test_static_assert
{
template <typename T>
struct check
{
static_assert(sizeof(int) <= sizeof(T), "not big enough");
};
}
namespace test_final_override
{
struct Base
{
virtual ~Base() {}
virtual void f() {}
};
struct Derived : public Base
{
virtual ~Derived() override {}
virtual void f() override {}
};
}
namespace test_double_right_angle_brackets
{
template < typename T >
struct check {};
typedef check<void> single_type;
typedef check<check<void>> double_type;
typedef check<check<check<void>>> triple_type;
typedef check<check<check<check<void>>>> quadruple_type;
}
namespace test_decltype
{
int
f()
{
int a = 1;
decltype(a) b = 2;
return a + b;
}
}
namespace test_type_deduction
{
template < typename T1, typename T2 >
struct is_same
{
static const bool value = false;
};
template < typename T >
struct is_same<T, T>
{
static const bool value = true;
};
template < typename T1, typename T2 >
auto
add(T1 a1, T2 a2) -> decltype(a1 + a2)
{
return a1 + a2;
}
int
test(const int c, volatile int v)
{
static_assert(is_same<int, decltype(0)>::value == true, "");
static_assert(is_same<int, decltype(c)>::value == false, "");
static_assert(is_same<int, decltype(v)>::value == false, "");
auto ac = c;
auto av = v;
auto sumi = ac + av + 'x';
auto sumf = ac + av + 1.0;
static_assert(is_same<int, decltype(ac)>::value == true, "");
static_assert(is_same<int, decltype(av)>::value == true, "");
static_assert(is_same<int, decltype(sumi)>::value == true, "");
static_assert(is_same<int, decltype(sumf)>::value == false, "");
static_assert(is_same<int, decltype(add(c, v))>::value == true, "");
return (sumf > 0.0) ? sumi : add(c, v);
}
}
namespace test_noexcept
{
int f() { return 0; }
int g() noexcept { return 0; }
static_assert(noexcept(f()) == false, "");
static_assert(noexcept(g()) == true, "");
}
namespace test_constexpr
{
template < typename CharT >
unsigned long constexpr
strlen_c_r(const CharT *const s, const unsigned long acc) noexcept
{
return *s ? strlen_c_r(s + 1, acc + 1) : acc;
}
template < typename CharT >
unsigned long constexpr
strlen_c(const CharT *const s) noexcept
{
return strlen_c_r(s, 0UL);
}
static_assert(strlen_c("") == 0UL, "");
static_assert(strlen_c("1") == 1UL, "");
static_assert(strlen_c("example") == 7UL, "");
static_assert(strlen_c("another\0example") == 7UL, "");
}
namespace test_rvalue_references
{
template < int N >
struct answer
{
static constexpr int value = N;
};
answer<1> f(int&) { return answer<1>(); }
answer<2> f(const int&) { return answer<2>(); }
answer<3> f(int&&) { return answer<3>(); }
void
test()
{
int i = 0;
const int c = 0;
static_assert(decltype(f(i))::value == 1, "");
static_assert(decltype(f(c))::value == 2, "");
static_assert(decltype(f(0))::value == 3, "");
}
}
namespace test_uniform_initialization
{
struct test
{
static const int zero {};
static const int one {1};
};
static_assert(test::zero == 0, "");
static_assert(test::one == 1, "");
}
namespace test_lambdas
{
void
test1()
{
auto lambda1 = [](){};
auto lambda2 = lambda1;
lambda1();
lambda2();
}
int
test2()
{
auto a = [](int i, int j){ return i + j; }(1, 2);
auto b = []() -> int { return '0'; }();
auto c = [=](){ return a + b; }();
auto d = [&](){ return c; }();
auto e = [a, &b](int x) mutable {
const auto identity = [](int y){ return y; };
for (auto i = 0; i < a; ++i)
a += b--;
return x + identity(a + b);
}(0);
return a + b + c + d + e;
}
int
test3()
{
const auto nullary = [](){ return 0; };
const auto unary = [](int x){ return x; };
using nullary_t = decltype(nullary);
using unary_t = decltype(unary);
const auto higher1st = [](nullary_t f){ return f(); };
const auto higher2nd = [unary](nullary_t f1){
return [unary, f1](unary_t f2){ return f2(unary(f1())); };
};
return higher1st(nullary) + higher2nd(nullary)(unary);
}
}
namespace test_variadic_templates
{
template <int...>
struct sum;
template <int N0, int... N1toN>
struct sum<N0, N1toN...>
{
static constexpr auto value = N0 + sum<N1toN...>::value;
};
template <>
struct sum<>
{
static constexpr auto value = 0;
};
static_assert(sum<>::value == 0, "");
static_assert(sum<1>::value == 1, "");
static_assert(sum<23>::value == 23, "");
static_assert(sum<1, 2>::value == 3, "");
static_assert(sum<5, 5, 11>::value == 21, "");
static_assert(sum<2, 3, 5, 7, 11, 13>::value == 41, "");
}
// http://stackoverflow.com/questions/13728184/template-aliases-and-sfinae
// Clang 3.1 fails with headers of libstd++ 4.8.3 when using std::function
// because of this.
namespace test_template_alias_sfinae
{
struct foo {};
template<typename T>
using member = typename T::member_type;
template<typename T>
void func(...) {}
template<typename T>
void func(member<T>*) {}
void test();
void test() { func<foo>(0); }
}
} // namespace cxx11
#endif // __cplusplus >= 201103L
]])
dnl Tests for new features in C++14
m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_14], [[
// If the compiler admits that it is not ready for C++14, why torture it?
// Hopefully, this will speed up the test.
#ifndef __cplusplus
#error "This is not a C++ compiler"
#elif __cplusplus < 201402L
#error "This is not a C++14 compiler"
#else
namespace cxx14
{
namespace test_polymorphic_lambdas
{
int
test()
{
const auto lambda = [](auto&&... args){
const auto istiny = [](auto x){
return (sizeof(x) == 1UL) ? 1 : 0;
};
const int aretiny[] = { istiny(args)... };
return aretiny[0];
};
return lambda(1, 1L, 1.0f, '1');
}
}
namespace test_binary_literals
{
constexpr auto ivii = 0b0000000000101010;
static_assert(ivii == 42, "wrong value");
}
namespace test_generalized_constexpr
{
template < typename CharT >
constexpr unsigned long
strlen_c(const CharT *const s) noexcept
{
auto length = 0UL;
for (auto p = s; *p; ++p)
++length;
return length;
}
static_assert(strlen_c("") == 0UL, "");
static_assert(strlen_c("x") == 1UL, "");
static_assert(strlen_c("test") == 4UL, "");
static_assert(strlen_c("another\0test") == 7UL, "");
}
namespace test_lambda_init_capture
{
int
test()
{
auto x = 0;
const auto lambda1 = [a = x](int b){ return a + b; };
const auto lambda2 = [a = lambda1(x)](){ return a; };
return lambda2();
}
}
namespace test_digit_separators
{
constexpr auto ten_million = 100'000'000;
static_assert(ten_million == 100000000, "");
}
namespace test_return_type_deduction
{
auto f(int& x) { return x; }
decltype(auto) g(int& x) { return x; }
template < typename T1, typename T2 >
struct is_same
{
static constexpr auto value = false;
};
template < typename T >
struct is_same<T, T>
{
static constexpr auto value = true;
};
int
test()
{
auto x = 0;
static_assert(is_same<int, decltype(f(x))>::value, "");
static_assert(is_same<int&, decltype(g(x))>::value, "");
return x;
}
}
} // namespace cxx14
#endif // __cplusplus >= 201402L
]])
dnl Tests for new features in C++17
m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_17], [[
// If the compiler admits that it is not ready for C++17, why torture it?
// Hopefully, this will speed up the test.
#ifndef __cplusplus
#error "This is not a C++ compiler"
#elif __cplusplus < 201703L
#error "This is not a C++17 compiler"
#else
#include <initializer_list>
#include <utility>
#include <type_traits>
namespace cxx17
{
namespace test_constexpr_lambdas
{
constexpr int foo = [](){return 42;}();
}
namespace test::nested_namespace::definitions
{
}
namespace test_fold_expression
{
template<typename... Args>
int multiply(Args... args)
{
return (args * ... * 1);
}
template<typename... Args>
bool all(Args... args)
{
return (args && ...);
}
}
namespace test_extended_static_assert
{
static_assert (true);
}
namespace test_auto_brace_init_list
{
auto foo = {5};
auto bar {5};
static_assert(std::is_same<std::initializer_list<int>, decltype(foo)>::value);
static_assert(std::is_same<int, decltype(bar)>::value);
}
namespace test_typename_in_template_template_parameter
{
template<template<typename> typename X> struct D;
}
namespace test_fallthrough_nodiscard_maybe_unused_attributes
{
int f1()
{
return 42;
}
[[nodiscard]] int f2()
{
[[maybe_unused]] auto unused = f1();
switch (f1())
{
case 17:
f1();
[[fallthrough]];
case 42:
f1();
}
return f1();
}
}
namespace test_extended_aggregate_initialization
{
struct base1
{
int b1, b2 = 42;
};
struct base2
{
base2() {
b3 = 42;
}
int b3;
};
struct derived : base1, base2
{
int d;
};
derived d1 {{1, 2}, {}, 4}; // full initialization
derived d2 {{}, {}, 4}; // value-initialized bases
}
namespace test_general_range_based_for_loop
{
struct iter
{
int i;
int& operator* ()
{
return i;
}
const int& operator* () const
{
return i;
}
iter& operator++()
{
++i;
return *this;
}
};
struct sentinel
{
int i;
};
bool operator== (const iter& i, const sentinel& s)
{
return i.i == s.i;
}
bool operator!= (const iter& i, const sentinel& s)
{
return !(i == s);
}
struct range
{
iter begin() const
{
return {0};
}
sentinel end() const
{
return {5};
}
};
void f()
{
range r {};
for (auto i : r)
{
[[maybe_unused]] auto v = i;
}
}
}
namespace test_lambda_capture_asterisk_this_by_value
{
struct t
{
int i;
int foo()
{
return [*this]()
{
return i;
}();
}
};
}
namespace test_enum_class_construction
{
enum class byte : unsigned char
{};
byte foo {42};
}
namespace test_constexpr_if
{
template <bool cond>
int f ()
{
if constexpr(cond)
{
return 13;
}
else
{
return 42;
}
}
}
namespace test_selection_statement_with_initializer
{
int f()
{
return 13;
}
int f2()
{
if (auto i = f(); i > 0)
{
return 3;
}
switch (auto i = f(); i + 4)
{
case 17:
return 2;
default:
return 1;
}
}
}
namespace test_template_argument_deduction_for_class_templates
{
template <typename T1, typename T2>
struct pair
{
pair (T1 p1, T2 p2)
: m1 {p1},
m2 {p2}
{}
T1 m1;
T2 m2;
};
void f()
{
[[maybe_unused]] auto p = pair{13, 42u};
}
}
namespace test_non_type_auto_template_parameters
{
template <auto n>
struct B
{};
B<5> b1;
B<'a'> b2;
}
namespace test_structured_bindings
{
int arr[2] = { 1, 2 };
std::pair<int, int> pr = { 1, 2 };
auto f1() -> int(&)[2]
{
return arr;
}
auto f2() -> std::pair<int, int>&
{
return pr;
}
struct S
{
int x1 : 2;
volatile double y1;
};
S f3()
{
return {};
}
auto [ x1, y1 ] = f1();
auto& [ xr1, yr1 ] = f1();
auto [ x2, y2 ] = f2();
auto& [ xr2, yr2 ] = f2();
const auto [ x3, y3 ] = f3();
}
namespace test_exception_spec_type_system
{
struct Good {};
struct Bad {};
void g1() noexcept;
void g2();
template<typename T>
Bad
f(T*, T*);
template<typename T1, typename T2>
Good
f(T1*, T2*);
static_assert (std::is_same_v<Good, decltype(f(g1, g2))>);
}
namespace test_inline_variables
{
template<class T> void f(T)
{}
template<class T> inline T g(T)
{
return T{};
}
template<> inline void f<>(int)
{}
template<> int g<>(int)
{
return 5;
}
}
} // namespace cxx17
#endif // __cplusplus < 201703L
]])
dnl Tests for new features in C++20
m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_20], [[
#ifndef __cplusplus
#error "This is not a C++ compiler"
#elif __cplusplus < 202002L
#error "This is not a C++20 compiler"
#else
#include <version>
namespace cxx20
{
// As C++20 supports feature test macros in the standard, there is no
// immediate need to actually test for feature availability on the
// Autoconf side.
} // namespace cxx20
#endif // __cplusplus < 202002L
]])

275
php-sdl3/build/pkg.m4 Normal file
View File

@ -0,0 +1,275 @@
# pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*-
# serial 12 (pkg-config-0.29.2)
dnl Copyright © 2004 Scott James Remnant <scott@netsplit.com>.
dnl Copyright © 2012-2015 Dan Nicholson <dbn.lists@gmail.com>
dnl
dnl This program is free software; you can redistribute it and/or modify
dnl it under the terms of the GNU General Public License as published by
dnl the Free Software Foundation; either version 2 of the License, or
dnl (at your option) any later version.
dnl
dnl This program is distributed in the hope that it will be useful, but
dnl WITHOUT ANY WARRANTY; without even the implied warranty of
dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
dnl General Public License for more details.
dnl
dnl You should have received a copy of the GNU General Public License
dnl along with this program; if not, write to the Free Software
dnl Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
dnl 02110-1301, USA.
dnl
dnl As a special exception to the GNU General Public License, if you
dnl distribute this file as part of a program that contains a
dnl configuration script generated by Autoconf, you may include it under
dnl the same distribution terms that you use for the rest of that
dnl program.
dnl PKG_PREREQ(MIN-VERSION)
dnl -----------------------
dnl Since: 0.29
dnl
dnl Verify that the version of the pkg-config macros are at least
dnl MIN-VERSION. Unlike PKG_PROG_PKG_CONFIG, which checks the user's
dnl installed version of pkg-config, this checks the developer's version
dnl of pkg.m4 when generating configure.
dnl
dnl To ensure that this macro is defined, also add:
dnl m4_ifndef([PKG_PREREQ],
dnl [m4_fatal([must install pkg-config 0.29 or later before running autoconf/autogen])])
dnl
dnl See the "Since" comment for each macro you use to see what version
dnl of the macros you require.
m4_defun([PKG_PREREQ],
[m4_define([PKG_MACROS_VERSION], [0.29.2])
m4_if(m4_version_compare(PKG_MACROS_VERSION, [$1]), -1,
[m4_fatal([pkg.m4 version $1 or higher is required but ]PKG_MACROS_VERSION[ found])])
])dnl PKG_PREREQ
dnl PKG_PROG_PKG_CONFIG([MIN-VERSION])
dnl ----------------------------------
dnl Since: 0.16
dnl
dnl Search for the pkg-config tool and set the PKG_CONFIG variable to
dnl first found in the path. Checks that the version of pkg-config found
dnl is at least MIN-VERSION. If MIN-VERSION is not specified, 0.9.0 is
dnl used since that's the first version where most current features of
dnl pkg-config existed.
AC_DEFUN([PKG_PROG_PKG_CONFIG],
[m4_pattern_forbid([^_?PKG_[A-Z_]+$])
m4_pattern_allow([^PKG_CONFIG(_(PATH|LIBDIR|SYSROOT_DIR|ALLOW_SYSTEM_(CFLAGS|LIBS)))?$])
m4_pattern_allow([^PKG_CONFIG_(DISABLE_UNINSTALLED|TOP_BUILD_DIR|DEBUG_SPEW)$])
AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility])
AC_ARG_VAR([PKG_CONFIG_PATH], [directories to add to pkg-config's search path])
AC_ARG_VAR([PKG_CONFIG_LIBDIR], [path overriding pkg-config's built-in search path])
if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then
AC_PATH_TOOL([PKG_CONFIG], [pkg-config])
fi
if test -n "$PKG_CONFIG"; then
_pkg_min_version=m4_default([$1], [0.9.0])
AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version])
if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then
AC_MSG_RESULT([yes])
else
AC_MSG_RESULT([no])
PKG_CONFIG=""
fi
fi[]dnl
])dnl PKG_PROG_PKG_CONFIG
dnl PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
dnl -------------------------------------------------------------------
dnl Since: 0.18
dnl
dnl Check to see whether a particular set of modules exists. Similar to
dnl PKG_CHECK_MODULES(), but does not set variables or print errors.
dnl
dnl Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG])
dnl only at the first occurrence in configure.ac, so if the first place
dnl it's called might be skipped (such as if it is within an "if", you
dnl have to call PKG_CHECK_EXISTS manually
AC_DEFUN([PKG_CHECK_EXISTS],
[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
if test -n "$PKG_CONFIG" && \
AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then
m4_default([$2], [:])
m4_ifvaln([$3], [else
$3])dnl
fi])
dnl _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES])
dnl ---------------------------------------------
dnl Internal wrapper calling pkg-config via PKG_CONFIG and setting
dnl pkg_failed based on the result.
m4_define([_PKG_CONFIG],
[if test -n "$$1"; then
pkg_cv_[]$1="$$1"
elif test -n "$PKG_CONFIG"; then
PKG_CHECK_EXISTS([$3],
[pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null`
test "x$?" != "x0" && pkg_failed=yes ],
[pkg_failed=yes])
else
pkg_failed=untried
fi[]dnl
])dnl _PKG_CONFIG
dnl _PKG_SHORT_ERRORS_SUPPORTED
dnl ---------------------------
dnl Internal check to see if pkg-config supports short errors.
AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED],
[AC_REQUIRE([PKG_PROG_PKG_CONFIG])
if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
_pkg_short_errors_supported=yes
else
_pkg_short_errors_supported=no
fi[]dnl
])dnl _PKG_SHORT_ERRORS_SUPPORTED
dnl PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND],
dnl [ACTION-IF-NOT-FOUND])
dnl --------------------------------------------------------------
dnl Since: 0.4.0
dnl
dnl Note that if there is a possibility the first call to
dnl PKG_CHECK_MODULES might not happen, you should be sure to include an
dnl explicit call to PKG_PROG_PKG_CONFIG in your configure.ac
AC_DEFUN([PKG_CHECK_MODULES],
[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl
AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl
pkg_failed=no
AC_MSG_CHECKING([for $2])
_PKG_CONFIG([$1][_CFLAGS], [cflags], [$2])
_PKG_CONFIG([$1][_LIBS], [libs], [$2])
m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS
and $1[]_LIBS to avoid the need to call pkg-config.
See the pkg-config man page for more details.])
if test $pkg_failed = yes; then
AC_MSG_RESULT([no])
_PKG_SHORT_ERRORS_SUPPORTED
if test $_pkg_short_errors_supported = yes; then
$1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1`
else
$1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1`
fi
# Put the nasty error message in config.log where it belongs
echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD
m4_default([$4], [AC_MSG_ERROR(
[Package requirements ($2) were not met:
$$1_PKG_ERRORS
Consider adjusting the PKG_CONFIG_PATH environment variable if you
installed software in a non-standard prefix.
_PKG_TEXT])[]dnl
])
elif test $pkg_failed = untried; then
AC_MSG_RESULT([no])
m4_default([$4], [AC_MSG_FAILURE(
[The pkg-config script could not be found or is too old. Make sure it
is in your PATH or set the PKG_CONFIG environment variable to the full
path to pkg-config.
_PKG_TEXT
To get pkg-config, see <http://pkg-config.freedesktop.org/>.])[]dnl
])
else
$1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS
$1[]_LIBS=$pkg_cv_[]$1[]_LIBS
AC_MSG_RESULT([yes])
$3
fi[]dnl
])dnl PKG_CHECK_MODULES
dnl PKG_CHECK_MODULES_STATIC(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND],
dnl [ACTION-IF-NOT-FOUND])
dnl ---------------------------------------------------------------------
dnl Since: 0.29
dnl
dnl Checks for existence of MODULES and gathers its build flags with
dnl static libraries enabled. Sets VARIABLE-PREFIX_CFLAGS from --cflags
dnl and VARIABLE-PREFIX_LIBS from --libs.
dnl
dnl Note that if there is a possibility the first call to
dnl PKG_CHECK_MODULES_STATIC might not happen, you should be sure to
dnl include an explicit call to PKG_PROG_PKG_CONFIG in your
dnl configure.ac.
AC_DEFUN([PKG_CHECK_MODULES_STATIC],
[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
_save_PKG_CONFIG=$PKG_CONFIG
PKG_CONFIG="$PKG_CONFIG --static"
PKG_CHECK_MODULES($@)
PKG_CONFIG=$_save_PKG_CONFIG[]dnl
])dnl PKG_CHECK_MODULES_STATIC
dnl PKG_INSTALLDIR([DIRECTORY])
dnl -------------------------
dnl Since: 0.27
dnl
dnl Substitutes the variable pkgconfigdir as the location where a module
dnl should install pkg-config .pc files. By default the directory is
dnl $libdir/pkgconfig, but the default can be changed by passing
dnl DIRECTORY. The user can override through the --with-pkgconfigdir
dnl parameter.
AC_DEFUN([PKG_INSTALLDIR],
[m4_pushdef([pkg_default], [m4_default([$1], ['${libdir}/pkgconfig'])])
m4_pushdef([pkg_description],
[pkg-config installation directory @<:@]pkg_default[@:>@])
AC_ARG_WITH([pkgconfigdir],
[AS_HELP_STRING([--with-pkgconfigdir], pkg_description)],,
[with_pkgconfigdir=]pkg_default)
AC_SUBST([pkgconfigdir], [$with_pkgconfigdir])
m4_popdef([pkg_default])
m4_popdef([pkg_description])
])dnl PKG_INSTALLDIR
dnl PKG_NOARCH_INSTALLDIR([DIRECTORY])
dnl --------------------------------
dnl Since: 0.27
dnl
dnl Substitutes the variable noarch_pkgconfigdir as the location where a
dnl module should install arch-independent pkg-config .pc files. By
dnl default the directory is $datadir/pkgconfig, but the default can be
dnl changed by passing DIRECTORY. The user can override through the
dnl --with-noarch-pkgconfigdir parameter.
AC_DEFUN([PKG_NOARCH_INSTALLDIR],
[m4_pushdef([pkg_default], [m4_default([$1], ['${datadir}/pkgconfig'])])
m4_pushdef([pkg_description],
[pkg-config arch-independent installation directory @<:@]pkg_default[@:>@])
AC_ARG_WITH([noarch-pkgconfigdir],
[AS_HELP_STRING([--with-noarch-pkgconfigdir], pkg_description)],,
[with_noarch_pkgconfigdir=]pkg_default)
AC_SUBST([noarch_pkgconfigdir], [$with_noarch_pkgconfigdir])
m4_popdef([pkg_default])
m4_popdef([pkg_description])
])dnl PKG_NOARCH_INSTALLDIR
dnl PKG_CHECK_VAR(VARIABLE, MODULE, CONFIG-VARIABLE,
dnl [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
dnl -------------------------------------------
dnl Since: 0.28
dnl
dnl Retrieves the value of the pkg-config variable for the given module.
AC_DEFUN([PKG_CHECK_VAR],
[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
AC_ARG_VAR([$1], [value of $3 for $2, overriding pkg-config])dnl
_PKG_CONFIG([$1], [variable="][$3]["], [$2])
AS_VAR_COPY([$1], [pkg_cv_][$1])
AS_VAR_IF([$1], [""], [$5], [$4])dnl
])dnl PKG_CHECK_VAR

1814
php-sdl3/build/shtool Executable file

File diff suppressed because it is too large Load Diff

58
php-sdl3/config.h Normal file
View File

@ -0,0 +1,58 @@
/* config.h. Generated from config.h.in by configure. */
/* config.h.in. Generated from configure.ac by autoheader. */
/* Define to 1 if the PHP extension 'sdl3' is built as a dynamic module. */
#define COMPILE_DL_SDL3 1
/* Define to 1 if you have the <dlfcn.h> header file. */
#define HAVE_DLFCN_H 1
/* Define to 1 if you have the <inttypes.h> header file. */
#define HAVE_INTTYPES_H 1
/* Define to 1 if you have the <stdint.h> header file. */
#define HAVE_STDINT_H 1
/* Define to 1 if you have the <stdio.h> header file. */
#define HAVE_STDIO_H 1
/* Define to 1 if you have the <stdlib.h> header file. */
#define HAVE_STDLIB_H 1
/* Define to 1 if you have the <strings.h> header file. */
#define HAVE_STRINGS_H 1
/* Define to 1 if you have the <string.h> header file. */
#define HAVE_STRING_H 1
/* Define to 1 if you have the <sys/stat.h> header file. */
#define HAVE_SYS_STAT_H 1
/* Define to 1 if you have the <sys/types.h> header file. */
#define HAVE_SYS_TYPES_H 1
/* Define to 1 if you have the <unistd.h> header file. */
#define HAVE_UNISTD_H 1
/* Define to the address where bug reports for this package should be sent. */
/* #undef PACKAGE_BUGREPORT */
/* Define to the full name of this package. */
/* #undef PACKAGE_NAME */
/* Define to the full name and version of this package. */
/* #undef PACKAGE_STRING */
/* Define to the one symbol short name of this package. */
/* #undef PACKAGE_TARNAME */
/* Define to the home page for this package. */
/* #undef PACKAGE_URL */
/* Define to the version of this package. */
/* #undef PACKAGE_VERSION */
/* Define to 1 if all of the C89 standard headers exist (not just the ones
required in a freestanding environment). This macro is provided for
backward compatibility; new code need not use it. */
#define STDC_HEADERS 1

57
php-sdl3/config.h.in Normal file
View File

@ -0,0 +1,57 @@
/* config.h.in. Generated from configure.ac by autoheader. */
/* Define to 1 if the PHP extension 'sdl3' is built as a dynamic module. */
#undef COMPILE_DL_SDL3
/* Define to 1 if you have the <dlfcn.h> header file. */
#undef HAVE_DLFCN_H
/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H
/* Define to 1 if you have the <stdint.h> header file. */
#undef HAVE_STDINT_H
/* Define to 1 if you have the <stdio.h> header file. */
#undef HAVE_STDIO_H
/* Define to 1 if you have the <stdlib.h> header file. */
#undef HAVE_STDLIB_H
/* Define to 1 if you have the <strings.h> header file. */
#undef HAVE_STRINGS_H
/* Define to 1 if you have the <string.h> header file. */
#undef HAVE_STRING_H
/* Define to 1 if you have the <sys/stat.h> header file. */
#undef HAVE_SYS_STAT_H
/* Define to 1 if you have the <sys/types.h> header file. */
#undef HAVE_SYS_TYPES_H
/* Define to 1 if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
/* Define to the address where bug reports for this package should be sent. */
/* #undef PACKAGE_BUGREPORT */
/* Define to the full name of this package. */
/* #undef PACKAGE_NAME */
/* Define to the full name and version of this package. */
/* #undef PACKAGE_STRING */
/* Define to the one symbol short name of this package. */
/* #undef PACKAGE_TARNAME */
/* Define to the home page for this package. */
/* #undef PACKAGE_URL */
/* Define to the version of this package. */
/* #undef PACKAGE_VERSION */
/* Define to 1 if all of the C89 standard headers exist (not just the ones
required in a freestanding environment). This macro is provided for
backward compatibility; new code need not use it. */
#undef STDC_HEADERS

37
php-sdl3/config.m4 Normal file
View File

@ -0,0 +1,37 @@
PHP_ARG_WITH(sdl3, [for sdl3 support], [
AS_HELP_STRING([--with-sdl3[=DIR]], [Enable sdl3 support. DIR is the prefix for SDL3 installation.])
])
PHP_ARG_WITH(sdl3_gfx, [for sdl3_gfx support], [
AS_HELP_STRING([--with-sdl3-gfx[=DIR]], [Enable sdl3_gfx support. DIR is the prefix for SDL3_gfx installation.])
])
if test "$PHP_SDL3" != "no"; then
if test -d "$PHP_SDL3"; then
PKG_CONFIG_PATH="$PHP_SDL3/lib/pkgconfig:$PHP_SDL3/share/pkgconfig:$PKG_CONFIG_PATH"
fi
PKG_CHECK_MODULES([SDL3], [sdl3 >= 3.0.0], [
CFLAGS="$CFLAGS $SDL3_CFLAGS"
LDFLAGS="$LDFLAGS $SDL3_LIBS"
],[
AC_MSG_ERROR([SDL3 not found. Please check your installation or use --with-sdl3=/path/to/sdl3])
])
if test "$PHP_SDL3_GFX" != "no"; then
if test -d "$PHP_SDL3_GFX"; then
PKG_CONFIG_PATH="$PHP_SDL3_GFX/lib/pkgconfig:$PHP_SDL3_GFX/share/pkgconfig:$PKG_CONFIG_PATH"
fi
PKG_CHECK_MODULES([SDL3_GFX], [sdl3-gfx >= 1.0.0], [
CFLAGS="$CFLAGS $SDL3_GFX_CFLAGS"
LDFLAGS="$LDFLAGS $SDL3_GFX_LIBS"
],[
AC_MSG_ERROR([SDL3_gfx not found. Please check your installation or use --with-sdl3-gfx=/path/to/sdl3_gfx])
])
fi
SDL_SOURCE_FILES="sdl3.c helper.c"
PHP_NEW_EXTENSION(sdl3, $SDL_SOURCE_FILES, $ext_shared)
fi

7
php-sdl3/config.nice Executable file
View File

@ -0,0 +1,7 @@
#! /bin/sh
#
# Created by configure
'./configure' \
'--with-sdl3-gfx=/usr/local' \
"$@"

782
php-sdl3/config.status Executable file
View File

@ -0,0 +1,782 @@
#! /bin/bash
# Generated by configure.
# Run this file to recreate the current configuration.
# Compiler output produced by configure, useful for debugging
# configure, is in config.log if it exists.
debug=false
ac_cs_recheck=false
ac_cs_silent=false
SHELL=${CONFIG_SHELL-/bin/bash}
export SHELL
## -------------------- ##
## M4sh Initialization. ##
## -------------------- ##
# Be more Bourne compatible
DUALCASE=1; export DUALCASE # for MKS sh
if test ${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1
then :
emulate sh
NULLCMD=:
# Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
# is contrary to our usage. Disable this feature.
alias -g '${1+"$@"}'='"$@"'
setopt NO_GLOB_SUBST
else case e in #(
e) case `(set -o) 2>/dev/null` in #(
*posix*) :
set -o posix ;; #(
*) :
;;
esac ;;
esac
fi
# Reset variables that may have inherited troublesome values from
# the environment.
# IFS needs to be set, to space, tab, and newline, in precisely that order.
# (If _AS_PATH_WALK were called with IFS unset, it would have the
# side effect of setting IFS to empty, thus disabling word splitting.)
# Quoting is to prevent editors from complaining about space-tab.
as_nl='
'
export as_nl
IFS=" "" $as_nl"
PS1='$ '
PS2='> '
PS4='+ '
# Ensure predictable behavior from utilities with locale-dependent output.
LC_ALL=C
export LC_ALL
LANGUAGE=C
export LANGUAGE
# We cannot yet rely on "unset" to work, but we need these variables
# to be unset--not just set to an empty or harmless value--now, to
# avoid bugs in old shells (e.g. pre-3.0 UWIN ksh). This construct
# also avoids known problems related to "unset" and subshell syntax
# in other old shells (e.g. bash 2.01 and pdksh 5.2.14).
for as_var in BASH_ENV ENV MAIL MAILPATH CDPATH
do eval test \${$as_var+y} \
&& ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
done
# Ensure that fds 0, 1, and 2 are open.
if (exec 3>&0) 2>/dev/null; then :; else exec 0</dev/null; fi
if (exec 3>&1) 2>/dev/null; then :; else exec 1>/dev/null; fi
if (exec 3>&2) ; then :; else exec 2>/dev/null; fi
# The user is always right.
if ${PATH_SEPARATOR+false} :; then
PATH_SEPARATOR=:
(PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
(PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
PATH_SEPARATOR=';'
}
fi
# Find who we are. Look in the path if we contain no directory separator.
as_myself=
case $0 in #((
*[\\/]* ) as_myself=$0 ;;
*) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
IFS=$as_save_IFS
case $as_dir in #(((
'') as_dir=./ ;;
*/) ;;
*) as_dir=$as_dir/ ;;
esac
test -r "$as_dir$0" && as_myself=$as_dir$0 && break
done
IFS=$as_save_IFS
;;
esac
# We did not find ourselves, most probably we were run as 'sh COMMAND'
# in which case we are not to be found in the path.
if test "x$as_myself" = x; then
as_myself=$0
fi
if test ! -f "$as_myself"; then
printf "%s\n" "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
exit 1
fi
# as_fn_error STATUS ERROR [LINENO LOG_FD]
# ----------------------------------------
# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
# script with STATUS, using 1 if that was 0.
as_fn_error ()
{
as_status=$1; test $as_status -eq 0 && as_status=1
if test "$4"; then
as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
fi
printf "%s\n" "$as_me: error: $2" >&2
as_fn_exit $as_status
} # as_fn_error
# as_fn_set_status STATUS
# -----------------------
# Set $? to STATUS, without forking.
as_fn_set_status ()
{
return $1
} # as_fn_set_status
# as_fn_exit STATUS
# -----------------
# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
as_fn_exit ()
{
set +e
as_fn_set_status $1
exit $1
} # as_fn_exit
# as_fn_unset VAR
# ---------------
# Portably unset VAR.
as_fn_unset ()
{
{ eval $1=; unset $1;}
}
as_unset=as_fn_unset
# as_fn_append VAR VALUE
# ----------------------
# Append the text in VALUE to the end of the definition contained in VAR. Take
# advantage of any shell optimizations that allow amortized linear growth over
# repeated appends, instead of the typical quadratic growth present in naive
# implementations.
if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null
then :
eval 'as_fn_append ()
{
eval $1+=\$2
}'
else case e in #(
e) as_fn_append ()
{
eval $1=\$$1\$2
} ;;
esac
fi # as_fn_append
# as_fn_arith ARG...
# ------------------
# Perform arithmetic evaluation on the ARGs, and store the result in the
# global $as_val. Take advantage of shells that can avoid forks. The arguments
# must be portable across $(()) and expr.
if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null
then :
eval 'as_fn_arith ()
{
as_val=$(( $* ))
}'
else case e in #(
e) as_fn_arith ()
{
as_val=`expr "$@" || test $? -eq 1`
} ;;
esac
fi # as_fn_arith
if expr a : '\(a\)' >/dev/null 2>&1 &&
test "X`expr 00001 : '.*\(...\)'`" = X001; then
as_expr=expr
else
as_expr=false
fi
if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
as_basename=basename
else
as_basename=false
fi
if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
as_dirname=dirname
else
as_dirname=false
fi
as_me=`$as_basename -- "$0" ||
$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
X"$0" : 'X\(//\)$' \| \
X"$0" : 'X\(/\)' \| . 2>/dev/null ||
printf "%s\n" X/"$0" |
sed '/^.*\/\([^/][^/]*\)\/*$/{
s//\1/
q
}
/^X\/\(\/\/\)$/{
s//\1/
q
}
/^X\/\(\/\).*/{
s//\1/
q
}
s/.*/./; q'`
# Avoid depending upon Character Ranges.
as_cr_letters='abcdefghijklmnopqrstuvwxyz'
as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
as_cr_Letters=$as_cr_letters$as_cr_LETTERS
as_cr_digits='0123456789'
as_cr_alnum=$as_cr_Letters$as_cr_digits
# Determine whether it's possible to make 'echo' print without a newline.
# These variables are no longer used directly by Autoconf, but are AC_SUBSTed
# for compatibility with existing Makefiles.
ECHO_C= ECHO_N= ECHO_T=
case `echo -n x` in #(((((
-n*)
case `echo 'xy\c'` in
*c*) ECHO_T=' ';; # ECHO_T is single tab character.
xy) ECHO_C='\c';;
*) echo `echo ksh88 bug on AIX 6.1` > /dev/null
ECHO_T=' ';;
esac;;
*)
ECHO_N='-n';;
esac
# For backward compatibility with old third-party macros, we provide
# the shell variables $as_echo and $as_echo_n. New code should use
# AS_ECHO(["message"]) and AS_ECHO_N(["message"]), respectively.
as_echo='printf %s\n'
as_echo_n='printf %s'
rm -f conf$$ conf$$.exe conf$$.file
if test -d conf$$.dir; then
rm -f conf$$.dir/conf$$.file
else
rm -f conf$$.dir
mkdir conf$$.dir 2>/dev/null
fi
if (echo >conf$$.file) 2>/dev/null; then
if ln -s conf$$.file conf$$ 2>/dev/null; then
as_ln_s='ln -s'
# ... but there are two gotchas:
# 1) On MSYS, both 'ln -s file dir' and 'ln file dir' fail.
# 2) DJGPP < 2.04 has no symlinks; 'ln -s' creates a wrapper executable.
# In both cases, we have to default to 'cp -pR'.
ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
as_ln_s='cp -pR'
elif ln conf$$.file conf$$ 2>/dev/null; then
as_ln_s=ln
else
as_ln_s='cp -pR'
fi
else
as_ln_s='cp -pR'
fi
rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
rmdir conf$$.dir 2>/dev/null
# as_fn_mkdir_p
# -------------
# Create "$as_dir" as a directory, including parents if necessary.
as_fn_mkdir_p ()
{
case $as_dir in #(
-*) as_dir=./$as_dir;;
esac
test -d "$as_dir" || eval $as_mkdir_p || {
as_dirs=
while :; do
case $as_dir in #(
*\'*) as_qdir=`printf "%s\n" "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
*) as_qdir=$as_dir;;
esac
as_dirs="'$as_qdir' $as_dirs"
as_dir=`$as_dirname -- "$as_dir" ||
$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
X"$as_dir" : 'X\(//\)[^/]' \| \
X"$as_dir" : 'X\(//\)$' \| \
X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
printf "%s\n" X"$as_dir" |
sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
s//\1/
q
}
/^X\(\/\/\)[^/].*/{
s//\1/
q
}
/^X\(\/\/\)$/{
s//\1/
q
}
/^X\(\/\).*/{
s//\1/
q
}
s/.*/./; q'`
test -d "$as_dir" && break
done
test -z "$as_dirs" || eval "mkdir $as_dirs"
} || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
} # as_fn_mkdir_p
if mkdir -p . 2>/dev/null; then
as_mkdir_p='mkdir -p "$as_dir"'
else
test -d ./-p && rmdir ./-p
as_mkdir_p=false
fi
# as_fn_executable_p FILE
# -----------------------
# Test if FILE is an executable regular file.
as_fn_executable_p ()
{
test -f "$1" && test -x "$1"
} # as_fn_executable_p
as_test_x='test -x'
as_executable_p=as_fn_executable_p
# Sed expression to map a string onto a valid CPP name.
as_sed_cpp="y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g"
as_tr_cpp="eval sed '$as_sed_cpp'" # deprecated
# Sed expression to map a string onto a valid variable name.
as_sed_sh="y%*+%pp%;s%[^_$as_cr_alnum]%_%g"
as_tr_sh="eval sed '$as_sed_sh'" # deprecated
exec 6>&1
## ----------------------------------- ##
## Main body of $CONFIG_STATUS script. ##
## ----------------------------------- ##
# Save the log message, to keep $0 and so on meaningful, and to
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
This file was extended by $as_me, which was
generated by GNU Autoconf 2.72. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
CONFIG_HEADERS = $CONFIG_HEADERS
CONFIG_LINKS = $CONFIG_LINKS
CONFIG_COMMANDS = $CONFIG_COMMANDS
$ $0 $@
on `(hostname || uname -n) 2>/dev/null | sed 1q`
"
# Files that config.status was made for.
config_headers=" config.h"
ac_cs_usage="\
'$as_me' instantiates files and other configuration actions
from templates according to the current configuration. Unless the files
and actions are specified as TAGs, all are instantiated by default.
Usage: $0 [OPTION]... [TAG]...
-h, --help print this help, then exit
-V, --version print version number and configuration settings, then exit
--config print configuration, then exit
-q, --quiet, --silent
do not print progress messages
-d, --debug don't remove temporary files
--recheck update $as_me by reconfiguring in the same conditions
--header=FILE[:TEMPLATE]
instantiate the configuration header FILE
Configuration headers:
$config_headers
Report bugs to the package provider."
ac_cs_config='--with-sdl3-gfx=/usr/local'
ac_cs_version="\
config.status
configured by ./configure, generated by GNU Autoconf 2.72,
with options \"$ac_cs_config\"
Copyright (C) 2023 Free Software Foundation, Inc.
This config.status script is free software; the Free Software Foundation
gives unlimited permission to copy, distribute and modify it."
ac_pwd='/home/thomas/projekte/phpnative/framework/php-sdl3'
srcdir='.'
test -n "$AWK" || AWK=awk
# The default lists apply if the user does not specify any file.
ac_need_defaults=:
while test $# != 0
do
case $1 in
--*=?*)
ac_option=`expr "X$1" : 'X\([^=]*\)='`
ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'`
ac_shift=:
;;
--*=)
ac_option=`expr "X$1" : 'X\([^=]*\)='`
ac_optarg=
ac_shift=:
;;
*)
ac_option=$1
ac_optarg=$2
ac_shift=shift
;;
esac
case $ac_option in
# Handling of the options.
-recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
ac_cs_recheck=: ;;
--version | --versio | --versi | --vers | --ver | --ve | --v | -V )
printf "%s\n" "$ac_cs_version"; exit ;;
--config | --confi | --conf | --con | --co | --c )
printf "%s\n" "$ac_cs_config"; exit ;;
--debug | --debu | --deb | --de | --d | -d )
debug=: ;;
--header | --heade | --head | --hea )
$ac_shift
case $ac_optarg in
*\'*) ac_optarg=`printf "%s\n" "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
esac
as_fn_append CONFIG_HEADERS " '$ac_optarg'"
ac_need_defaults=false;;
--he | --h)
# Conflict between --help and --header
as_fn_error $? "ambiguous option: '$1'
Try '$0 --help' for more information.";;
--help | --hel | -h )
printf "%s\n" "$ac_cs_usage"; exit ;;
-q | -quiet | --quiet | --quie | --qui | --qu | --q \
| -silent | --silent | --silen | --sile | --sil | --si | --s)
ac_cs_silent=: ;;
# This is an error.
-*) as_fn_error $? "unrecognized option: '$1'
Try '$0 --help' for more information." ;;
*) as_fn_append ac_config_targets " $1"
ac_need_defaults=false ;;
esac
shift
done
ac_configure_extra_args=
if $ac_cs_silent; then
exec 6>/dev/null
ac_configure_extra_args="$ac_configure_extra_args --silent"
fi
if $ac_cs_recheck; then
set X /bin/bash './configure' '--with-sdl3-gfx=/usr/local' $ac_configure_extra_args --no-create --no-recursion
shift
\printf "%s\n" "running CONFIG_SHELL=/bin/bash $*" >&6
CONFIG_SHELL='/bin/bash'
export CONFIG_SHELL
exec "$@"
fi
exec 5>>config.log
{
echo
sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
## Running $as_me. ##
_ASBOX
printf "%s\n" "$ac_log"
} >&5
# Handling of arguments.
for ac_config_target in $ac_config_targets
do
case $ac_config_target in
"config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;;
*) as_fn_error $? "invalid argument: '$ac_config_target'" "$LINENO" 5;;
esac
done
# If the user did not use the arguments to specify the items to instantiate,
# then the envvar interface is used. Set only those that are not.
# We use the long form for the default assignment because of an extremely
# bizarre bug on SunOS 4.1.3.
if $ac_need_defaults; then
test ${CONFIG_HEADERS+y} || CONFIG_HEADERS=$config_headers
fi
# Have a temporary directory for convenience. Make it in the build tree
# simply because there is no reason against having it here, and in addition,
# creating and moving files from /tmp can sometimes cause problems.
# Hook for its removal unless debugging.
# Note that there is a small window in which the directory will not be cleaned:
# after its creation but before its name has been assigned to '$tmp'.
$debug ||
{
tmp= ac_tmp=
trap 'exit_status=$?
: "${ac_tmp:=$tmp}"
{ test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status
' 0
trap 'as_fn_exit 1' 1 2 13 15
}
# Create a (secure) tmp directory for tmp files.
{
tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` &&
test -d "$tmp"
} ||
{
tmp=./conf$$-$RANDOM
(umask 077 && mkdir "$tmp")
} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5
ac_tmp=$tmp
# Set up the scripts for CONFIG_HEADERS section.
# No need to generate them if there are no CONFIG_HEADERS.
# This happens for instance with './config.status Makefile'.
if test -n "$CONFIG_HEADERS"; then
cat >"$ac_tmp/defines.awk" <<\_ACAWK ||
BEGIN {
D["PACKAGE_NAME"]=" \"\""
D["PACKAGE_TARNAME"]=" \"\""
D["PACKAGE_VERSION"]=" \"\""
D["PACKAGE_STRING"]=" \"\""
D["PACKAGE_BUGREPORT"]=" \"\""
D["PACKAGE_URL"]=" \"\""
D["COMPILE_DL_SDL3"]=" 1"
D["HAVE_STDIO_H"]=" 1"
D["HAVE_STDLIB_H"]=" 1"
D["HAVE_STRING_H"]=" 1"
D["HAVE_INTTYPES_H"]=" 1"
D["HAVE_STDINT_H"]=" 1"
D["HAVE_STRINGS_H"]=" 1"
D["HAVE_SYS_STAT_H"]=" 1"
D["HAVE_SYS_TYPES_H"]=" 1"
D["HAVE_UNISTD_H"]=" 1"
D["STDC_HEADERS"]=" 1"
D["HAVE_DLFCN_H"]=" 1"
for (key in D) D_is_set[key] = 1
FS = ""
}
/^[\t ]*#[\t ]*(define|undef)[\t ]+[_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ][_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789]*([\t (]|$)/ {
line = $ 0
split(line, arg, " ")
if (arg[1] == "#") {
defundef = arg[2]
mac1 = arg[3]
} else {
defundef = substr(arg[1], 2)
mac1 = arg[2]
}
split(mac1, mac2, "(") #)
macro = mac2[1]
prefix = substr(line, 1, index(line, defundef) - 1)
if (D_is_set[macro]) {
# Preserve the white space surrounding the "#".
print prefix "define", macro P[macro] D[macro]
next
} else {
# Replace #undef with comments. This is necessary, for example,
# in the case of _POSIX_SOURCE, which is predefined and required
# on some systems where configure will not decide to define it.
if (defundef == "undef") {
print "/*", prefix defundef, macro, "*/"
next
}
}
}
{ print }
_ACAWK
as_fn_error $? "could not setup config headers machinery" "$LINENO" 5
fi # test -n "$CONFIG_HEADERS"
eval set X " :H $CONFIG_HEADERS "
shift
for ac_tag
do
case $ac_tag in
:[FHLC]) ac_mode=$ac_tag; continue;;
esac
case $ac_mode$ac_tag in
:[FHL]*:*);;
:L* | :C*:*) as_fn_error $? "invalid tag '$ac_tag'" "$LINENO" 5;;
:[FH]-) ac_tag=-:-;;
:[FH]*) ac_tag=$ac_tag:$ac_tag.in;;
esac
ac_save_IFS=$IFS
IFS=:
set x $ac_tag
IFS=$ac_save_IFS
shift
ac_file=$1
shift
case $ac_mode in
:L) ac_source=$1;;
:[FH])
ac_file_inputs=
for ac_f
do
case $ac_f in
-) ac_f="$ac_tmp/stdin";;
*) # Look for the file first in the build tree, then in the source tree
# (if the path is not absolute). The absolute path cannot be DOS-style,
# because $ac_f cannot contain ':'.
test -f "$ac_f" ||
case $ac_f in
[\\/$]*) false;;
*) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;
esac ||
as_fn_error 1 "cannot find input file: '$ac_f'" "$LINENO" 5;;
esac
case $ac_f in *\'*) ac_f=`printf "%s\n" "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac
as_fn_append ac_file_inputs " '$ac_f'"
done
# Let's still pretend it is 'configure' which instantiates (i.e., don't
# use $as_me), people would be surprised to read:
# /* config.h. Generated by config.status. */
configure_input='Generated from '`
printf "%s\n" "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g'
`' by configure.'
if test x"$ac_file" != x-; then
configure_input="$ac_file. $configure_input"
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5
printf "%s\n" "$as_me: creating $ac_file" >&6;}
fi
# Neutralize special characters interpreted by sed in replacement strings.
case $configure_input in #(
*\&* | *\|* | *\\* )
ac_sed_conf_input=`printf "%s\n" "$configure_input" |
sed 's/[\\\\&|]/\\\\&/g'`;; #(
*) ac_sed_conf_input=$configure_input;;
esac
case $ac_tag in
*:-:* | *:-) cat >"$ac_tmp/stdin" \
|| as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;;
esac
;;
esac
ac_dir=`$as_dirname -- "$ac_file" ||
$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
X"$ac_file" : 'X\(//\)[^/]' \| \
X"$ac_file" : 'X\(//\)$' \| \
X"$ac_file" : 'X\(/\)' \| . 2>/dev/null ||
printf "%s\n" X"$ac_file" |
sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
s//\1/
q
}
/^X\(\/\/\)[^/].*/{
s//\1/
q
}
/^X\(\/\/\)$/{
s//\1/
q
}
/^X\(\/\).*/{
s//\1/
q
}
s/.*/./; q'`
as_dir="$ac_dir"; as_fn_mkdir_p
ac_builddir=.
case "$ac_dir" in
.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
*)
ac_dir_suffix=/`printf "%s\n" "$ac_dir" | sed 's|^\.[\\/]||'`
# A ".." for each directory in $ac_dir_suffix.
ac_top_builddir_sub=`printf "%s\n" "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
case $ac_top_builddir_sub in
"") ac_top_builddir_sub=. ac_top_build_prefix= ;;
*) ac_top_build_prefix=$ac_top_builddir_sub/ ;;
esac ;;
esac
ac_abs_top_builddir=$ac_pwd
ac_abs_builddir=$ac_pwd$ac_dir_suffix
# for backward compatibility:
ac_top_builddir=$ac_top_build_prefix
case $srcdir in
.) # We are building in place.
ac_srcdir=.
ac_top_srcdir=$ac_top_builddir_sub
ac_abs_top_srcdir=$ac_pwd ;;
[\\/]* | ?:[\\/]* ) # Absolute name.
ac_srcdir=$srcdir$ac_dir_suffix;
ac_top_srcdir=$srcdir
ac_abs_top_srcdir=$srcdir ;;
*) # Relative name.
ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
ac_top_srcdir=$ac_top_build_prefix$srcdir
ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
esac
ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
case $ac_mode in
:H)
#
# CONFIG_HEADER
#
if test x"$ac_file" != x-; then
{
printf "%s\n" "/* $configure_input */" >&1 \
&& eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs"
} >"$ac_tmp/config.h" \
|| as_fn_error $? "could not create $ac_file" "$LINENO" 5
if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5
printf "%s\n" "$as_me: $ac_file is unchanged" >&6;}
else
rm -f "$ac_file"
mv "$ac_tmp/config.h" "$ac_file" \
|| as_fn_error $? "could not create $ac_file" "$LINENO" 5
fi
else
printf "%s\n" "/* $configure_input */" >&1 \
&& eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \
|| as_fn_error $? "could not create -" "$LINENO" 5
fi
;;
esac
done # for ac_tag
as_fn_exit 0

14900
php-sdl3/configure vendored Executable file

File diff suppressed because it is too large Load Diff

200
php-sdl3/configure.ac Normal file
View File

@ -0,0 +1,200 @@
dnl This file becomes configure.ac for self-contained extensions.
dnl Include external macro definitions before the AC_INIT to also remove
dnl comments starting with # and empty newlines from the included files.
m4_include([build/ax_check_compile_flag.m4])
m4_include([build/ax_gcc_func_attribute.m4])
m4_include([build/libtool.m4])
m4_include([build/php_cxx_compile_stdcxx.m4])
m4_include([build/php.m4])
m4_include([build/pkg.m4])
AC_PREREQ([2.68])
AC_INIT
AC_CONFIG_SRCDIR([config.m4])
AC_CONFIG_AUX_DIR([build])
AC_PRESERVE_HELP_ORDER
PHP_CONFIG_NICE([config.nice])
AC_DEFUN([PHP_EXT_BUILDDIR],[.])dnl
AC_DEFUN([PHP_EXT_DIR],[""])dnl
AC_DEFUN([PHP_EXT_SRCDIR],[$abs_srcdir])dnl
AC_DEFUN([PHP_ALWAYS_SHARED],[
ext_output="yes, shared"
ext_shared=yes
test "[$]$1" = "no" && $1=yes
])dnl
PHP_INIT_BUILD_SYSTEM
PKG_PROG_PKG_CONFIG
AC_PROG_CC([cc gcc])
PHP_DETECT_ICC
PHP_DETECT_SUNCC
dnl Support systems with system libraries in e.g. /usr/lib64.
PHP_ARG_WITH([libdir],
[for system library directory],
[AS_HELP_STRING([--with-libdir=NAME],
[Look for libraries in .../NAME rather than .../lib])],
[lib],
[no])
PHP_RUNPATH_SWITCH
PHP_SHLIB_SUFFIX_NAMES
dnl Find php-config script.
PHP_ARG_WITH([php-config],,
[AS_HELP_STRING([--with-php-config=PATH],
[Path to php-config [php-config]])],
[php-config],
[no])
dnl For BC.
PHP_CONFIG=$PHP_PHP_CONFIG
prefix=$($PHP_CONFIG --prefix 2>/dev/null)
phpincludedir=$($PHP_CONFIG --include-dir 2>/dev/null)
INCLUDES=$($PHP_CONFIG --includes 2>/dev/null)
EXTENSION_DIR=$($PHP_CONFIG --extension-dir 2>/dev/null)
PHP_EXECUTABLE=$($PHP_CONFIG --php-binary 2>/dev/null)
AS_VAR_IF([prefix],,
[AC_MSG_ERROR([Cannot find php-config. Please use --with-php-config=PATH])])
AC_MSG_CHECKING([for PHP prefix])
AC_MSG_RESULT([$prefix])
AC_MSG_CHECKING([for PHP includes])
AC_MSG_RESULT([$INCLUDES])
AC_MSG_CHECKING([for PHP extension directory])
AC_MSG_RESULT([$EXTENSION_DIR])
AC_MSG_CHECKING([for PHP installed headers prefix])
AC_MSG_RESULT([$phpincludedir])
dnl Checks for PHP_DEBUG / ZEND_DEBUG / ZTS.
AC_MSG_CHECKING([if debugging is enabled])
old_CPPFLAGS=$CPPFLAGS
CPPFLAGS="-I$phpincludedir"
AC_EGREP_CPP([php_debug_is_enabled], [
#include <main/php_config.h>
#if ZEND_DEBUG
php_debug_is_enabled
#endif
],
[PHP_DEBUG=yes],
[PHP_DEBUG=no])
CPPFLAGS=$old_CPPFLAGS
AC_MSG_RESULT([$PHP_DEBUG])
AC_MSG_CHECKING([if PHP is built with thread safety (ZTS)])
old_CPPFLAGS=$CPPFLAGS
CPPFLAGS="-I$phpincludedir"
AC_EGREP_CPP([php_zts_is_enabled], [
#include <main/php_config.h>
#ifdef ZTS
php_zts_is_enabled
#endif
],
[PHP_THREAD_SAFETY=yes],
[PHP_THREAD_SAFETY=no])
CPPFLAGS=$old_CPPFLAGS
AC_MSG_RESULT([$PHP_THREAD_SAFETY])
dnl Discard optimization flags when debugging is enabled.
AS_VAR_IF([PHP_DEBUG], [yes], [
PHP_DEBUG=1
ZEND_DEBUG=yes
PHP_REMOVE_OPTIMIZATION_FLAGS
dnl Add -O0 only if GCC or ICC is used.
if test "$GCC" = "yes" || test "$ICC" = "yes"; then
CFLAGS="$CFLAGS -O0"
CXXFLAGS="$CXXFLAGS -g -O0"
fi
if test "$SUNCC" = "yes"; then
if test -n "$auto_cflags"; then
CFLAGS="-g"
CXXFLAGS="-g"
else
CFLAGS="$CFLAGS -g"
CXXFLAGS="$CFLAGS -g"
fi
fi
], [
PHP_DEBUG=0
ZEND_DEBUG=no
])
dnl Always shared.
PHP_BUILD_SHARED
PHP_HELP_SEPARATOR([Extension:])
PHP_CONFIGURE_PART([Configuring extension])
sinclude(config.m4)
enable_static=no
enable_shared=yes
PHP_HELP_SEPARATOR([Libtool:])
PHP_CONFIGURE_PART([Configuring libtool])
dnl Only allow AC_PROG_CXX and AC_PROG_CXXCPP if they are explicitly called (by
dnl PHP_REQUIRE_CXX). Otherwise AC_PROG_LIBTOOL fails if there is no working C++
dnl compiler.
AC_PROVIDE_IFELSE([PHP_REQUIRE_CXX], [], [
undefine([AC_PROG_CXX])
AC_DEFUN([AC_PROG_CXX], [])
undefine([AC_PROG_CXXCPP])
AC_DEFUN([AC_PROG_CXXCPP], [php_prog_cxxcpp=disabled])
])
AC_PROG_LIBTOOL
all_targets='$(PHP_MODULES) $(PHP_ZEND_EX)'
install_targets="install-modules install-headers"
CPPFLAGS="$CPPFLAGS -DHAVE_CONFIG_H"
CFLAGS_CLEAN='$(CFLAGS) -D_GNU_SOURCE'
CXXFLAGS_CLEAN='$(CXXFLAGS)'
AS_VAR_IF([prefix], [NONE], [prefix=/usr/local])
AS_VAR_IF([exec_prefix], [NONE], [exec_prefix='$(prefix)'])
AS_VAR_IF([cross_compiling], [yes],
[AC_CHECK_PROGS([BUILD_CC], [gcc clang c99 c89 cc cl], [none])
AC_MSG_CHECKING([for native build C compiler])
AC_MSG_RESULT([$BUILD_CC])],
[BUILD_CC=$CC])
PHP_SUBST([PHP_MODULES])
PHP_SUBST([PHP_ZEND_EX])
PHP_SUBST([all_targets])
PHP_SUBST([install_targets])
PHP_SUBST([prefix])
PHP_SUBST([exec_prefix])
PHP_SUBST([libdir])
PHP_SUBST([phpincludedir])
PHP_SUBST([CC])
PHP_SUBST([CFLAGS])
PHP_SUBST([CFLAGS_CLEAN])
PHP_SUBST([CPP])
PHP_SUBST([CPPFLAGS])
PHP_SUBST([CXX])
PHP_SUBST([CXXFLAGS])
PHP_SUBST([CXXFLAGS_CLEAN])
PHP_SUBST([EXTENSION_DIR])
PHP_SUBST([PHP_EXECUTABLE])
PHP_SUBST([EXTRA_LDFLAGS])
PHP_SUBST([EXTRA_LIBS])
PHP_SUBST([INCLUDES])
PHP_SUBST([LDFLAGS])
PHP_SUBST([LIBTOOL])
PHP_SUBST([SHELL])
PHP_SUBST([INSTALL_HEADERS])
PHP_SUBST([BUILD_CC])
PHP_CONFIGURE_PART([Generating files])
AC_CONFIG_HEADERS([config.h])
AC_CONFIG_COMMANDS_PRE([PHP_PATCH_CONFIG_HEADERS([config.h.in])])
AC_OUTPUT

52
php-sdl3/draw_rect.php Normal file
View File

@ -0,0 +1,52 @@
<?php
if (!extension_loaded('sdl3')) {
echo "Die Erweiterung 'sdl3' ist nicht geladen.\n";
exit(1);
}
// SDL_INIT_VIDEO
const SDL_INIT_VIDEO = 0x00000020;
if (!sdl_init(SDL_INIT_VIDEO)) {
echo "Fehler bei der Initialisierung von SDL: " . sdl_get_error() . "\n";
exit(1);
}
$window = sdl_create_window("PHP-SDL3 Fenster", 640, 480);
if (!$window) {
echo "Fehler beim Erstellen des Fensters: " . sdl_get_error() . "\n";
sdl_quit();
exit(1);
}
$renderer = sdl_create_renderer($window);
if (!$renderer) {
echo "Fehler beim Erstellen des Renderers: " . sdl_get_error() . "\n";
// Das Fenster wird durch den Resource Destructor zerstört
sdl_quit();
exit(1);
}
// Hintergrund blau machen
sdl_set_render_draw_color($renderer, 0, 0, 255, 255);
sdl_render_clear($renderer);
// Ein rotes Rechteck zeichnen
$rect = ['x' => 220, 'y' => 140, 'w' => 200, 'h' => 200];
sdl_set_render_draw_color($renderer, 255, 0, 0, 255);
sdl_render_fill_rect($renderer, $rect);
// Alles auf dem Bildschirm anzeigen
sdl_render_present($renderer);
// 3 Sekunden warten
sdl_delay(3000);
// SDL herunterfahren
// Die Ressourcen für Fenster und Renderer werden automatisch freigegeben
sdl_quit();
echo "Fenster wurde für 3 Sekunden angezeigt.\n";
?>

48
php-sdl3/draw_rounded.php Normal file
View File

@ -0,0 +1,48 @@
<?php
if (!extension_loaded('sdl3')) {
echo "Die Erweiterung 'sdl3' ist nicht geladen.\n";
exit(1);
}
// SDL_INIT_VIDEO
const SDL_INIT_VIDEO = 0x00000020;
if (!sdl_init(SDL_INIT_VIDEO)) {
echo "Fehler bei der Initialisierung von SDL: " . sdl_get_error() . "\n";
exit(1);
}
$window = sdl_create_window("PHP-SDL3 Abgerundetes Rechteck", 800, 600);
if (!$window) {
echo "Fehler beim Erstellen des Fensters: " . sdl_get_error() . "\n";
sdl_quit();
exit(1);
}
$renderer = sdl_create_renderer($window);
if (!$renderer) {
echo "Fehler beim Erstellen des Renderers: " . sdl_get_error() . "\n";
sdl_quit();
exit(1);
}
// Hintergrund dunkelgrau machen
sdl_set_render_draw_color($renderer, 50, 50, 50, 255);
sdl_render_clear($renderer);
// Ein blaues, abgerundetes Rechteck mit einem Radius von 20px zeichnen
sdl_rounded_box($renderer, 200, 150, 600, 450, 20, 30, 144, 255, 255);
// Alles auf dem Bildschirm anzeigen
sdl_render_present($renderer);
// 4 Sekunden warten
sdl_delay(4000);
sdl_quit();
echo "Fenster wurde für 4 Sekunden angezeigt.\n";
?>

View File

@ -0,0 +1,51 @@
<?php
if (!extension_loaded('sdl3')) {
echo "Die Erweiterung 'sdl3' ist nicht geladen.\n";
exit(1);
}
// SDL_INIT_VIDEO
const SDL_INIT_VIDEO = 0x00000020;
if (!sdl_init(SDL_INIT_VIDEO)) {
echo 'Fehler bei der Initialisierung von SDL: ' . sdl_get_error() . "\n";
exit(1);
}
$window = sdl_create_window('PHP-SDL3 EX Rechteck', 1024, 1024);
if (!$window) {
echo 'Fehler beim Erstellen des Fensters: ' . sdl_get_error() . "\n";
sdl_quit();
exit(1);
}
$renderer = sdl_create_renderer($window);
if (!$renderer) {
echo 'Fehler beim Erstellen des Renderers: ' . sdl_get_error() . "\n";
sdl_quit();
exit(1);
}
// Hintergrund dunkelgrau machen
sdl_set_render_draw_color($renderer, 50, 50, 50, 255);
sdl_render_clear($renderer);
// Ein grünes, abgerundetes Rechteck mit verschiedenen Radien zeichnen
// Radien: Oben-Links, Oben-Rechts, Unten-Rechts, Unten-Links
$rad_tl = 20;
$rad_tr = 20;
$rad_br = 20;
$rad_bl = 20;
sdl_rounded_box_ex($renderer, 100, 100, 200, 200, $rad_tl, $rad_tr, $rad_br, $rad_bl, 30, 200, 70, 255);
// Alles auf dem Bildschirm anzeigen
sdl_render_present($renderer);
// 4 Sekunden warten
sdl_delay(4000);
sdl_quit();
echo "Fenster wurde für 4 Sekunden angezeigt.\n";

5
php-sdl3/helper.c Normal file
View File

@ -0,0 +1,5 @@
#include "helper.h"
#include "math.h"
#include "SDL3/SDL.h"

2
php-sdl3/helper.dep Normal file
View File

@ -0,0 +1,2 @@
helper.lo: /home/thomas/projekte/phpnative/framework/php-sdl3/helper.c \
/home/thomas/projekte/phpnative/framework/php-sdl3/helper.h

36
php-sdl3/helper.h Normal file
View File

@ -0,0 +1,36 @@
#ifndef PHP_SDL3_HELPER
#define PHP_SDL3_HELPER
#include <SDL3/SDL.h>
#include "math.h"
static void draw_hline(SDL_Renderer *renderer, int x1, int x2, int y) {
if (x2 < x1) return;
SDL_RenderLine(renderer, x1, y, x2, y);
}
// Zeichnet einen gefüllten Viertel-Kreis (filled quarter circle).
// quadrant: 0 = top-left, 1 = top-right, 2 = bottom-right, 3 = bottom-left
static void filled_quarter_circle(SDL_Renderer *renderer, int cx, int cy, int r, int quadrant) {
if (r <= 0) return;
int r2 = r * r;
for (int dy = 0; dy <= r; ++dy) {
// dy ist vertikale Distanz vom Kreiszentrum (0..r)
int dx = (int)floor(sqrt((double)r2 - (double)dy * dy));
switch (quadrant) {
case 0: // top-left: y = cy - dy, x in [cx - dx, cx]
draw_hline(renderer, cx - dx, cx, cy - dy);
break;
case 1: // top-right: y = cy - dy, x in [cx, cx + dx]
draw_hline(renderer, cx, cx + dx, cy - dy);
break;
case 2: // bottom-right: y = cy + dy, x in [cx, cx + dx]
draw_hline(renderer, cx, cx + dx, cy + dy);
break;
case 3: // bottom-left: y = cy + dy, x in [cx - dx, cx]
draw_hline(renderer, cx - dx, cx, cy + dy);
break;
}
}
}
#endif

12
php-sdl3/helper.lo Normal file
View File

@ -0,0 +1,12 @@
# helper.lo - a libtool object file
# Generated by ltmain.sh - GNU libtool 1.5.26 (1.1220.2.492 2008/01/30 06:40:56)
#
# Please DO NOT delete this file!
# It is necessary for linking the library.
# Name of the PIC object.
pic_object='.libs/helper.o'
# Name of the non-PIC object.
non_pic_object=none

7326
php-sdl3/libtool Executable file

File diff suppressed because it is too large Load Diff

35
php-sdl3/modules/sdl3.la Normal file
View File

@ -0,0 +1,35 @@
# sdl3.la - a libtool library file
# Generated by ltmain.sh - GNU libtool 1.5.26 (1.1220.2.492 2008/01/30 06:40:56)
#
# Please DO NOT delete this file!
# It is necessary for linking the library.
# The name that we can dlopen(3).
dlname='sdl3.so'
# Names of this library.
library_names='sdl3.so sdl3.so sdl3.so'
# The name of the static archive.
old_library=''
# Libraries that this one depends upon.
dependency_libs=' -L/usr/local/lib -lSDL3_gfx -lSDL3'
# Version information for sdl3.
current=0
age=0
revision=0
# Is this an already installed library?
installed=yes
# Should we warn about portability when linking against -modules?
shouldnotlink=yes
# Files to dlopen/dlpreopen
dlopen=''
dlpreopen=''
# Directory that this library needs to be installed in:
libdir='/home/thomas/projekte/phpnative/framework/php-sdl3/modules'

BIN
php-sdl3/modules/sdl3.so Executable file

Binary file not shown.

9
php-sdl3/php_sdl3.h Normal file
View File

@ -0,0 +1,9 @@
#ifndef PHP_SDL3_H
#define PHP_SDL3_H
extern zend_module_entry sdl3_module_entry;
#define phpext_sdl3_ptr &sdl3_module_entry
#define PHP_SDL3_VERSION "0.1.0"
#endif

4166
php-sdl3/run-tests.php Normal file

File diff suppressed because it is too large Load Diff

368
php-sdl3/sdl3.c Normal file
View File

@ -0,0 +1,368 @@
#include <SDL3/SDL_stdinc.h>
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "php.h"
#include "php_sdl3.h"
#include "helper.h"
#include <SDL3/SDL.h>
#include <SDL3_gfx/SDL3_gfxPrimitives.h>
#include <math.h>
// Resource handles
static int le_sdl_window;
static int le_sdl_renderer;
// Destructor for window resource
static void sdl_window_dtor(zend_resource *rsrc) {
SDL_Window *win = (SDL_Window *)rsrc->ptr;
if (win) {
SDL_DestroyWindow(win);
}
}
// Destructor for renderer resource
static void sdl_renderer_dtor(zend_resource *rsrc) {
SDL_Renderer *ren = (SDL_Renderer *)rsrc->ptr;
if (ren) {
SDL_DestroyRenderer(ren);
}
}
PHP_MINIT_FUNCTION(sdl3) {
le_sdl_window = zend_register_list_destructors_ex(sdl_window_dtor, NULL, "SDL_Window", module_number);
le_sdl_renderer = zend_register_list_destructors_ex(sdl_renderer_dtor, NULL, "SDL_Renderer", module_number);
return SUCCESS;
}
PHP_FUNCTION(sdl_init) {
zend_long flags;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &flags) == FAILURE) {
RETURN_THROWS();
}
if (SDL_Init((Uint32)flags) < 0) {
RETURN_FALSE;
}
RETURN_TRUE;
}
PHP_FUNCTION(sdl_quit) {
SDL_Quit();
}
PHP_FUNCTION(sdl_create_window) {
char *title;
size_t title_len;
zend_long w, h;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "sll", &title, &title_len, &w, &h) == FAILURE) {
RETURN_THROWS();
}
SDL_Window *win = SDL_CreateWindow(title, (int)w, (int)h, 0);
if (!win) {
RETURN_FALSE;
}
RETURN_RES(zend_register_resource(win, le_sdl_window));
}
PHP_FUNCTION(sdl_create_renderer) {
zval *win_res;
SDL_Window *win;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &win_res) == FAILURE) {
RETURN_THROWS();
}
win = (SDL_Window *)zend_fetch_resource(Z_RES_P(win_res), "SDL_Window", le_sdl_window);
if (!win) {
RETURN_FALSE;
}
SDL_Renderer *ren = SDL_CreateRenderer(win, NULL);
if (!ren) {
RETURN_FALSE;
}
RETURN_RES(zend_register_resource(ren, le_sdl_renderer));
}
PHP_FUNCTION(sdl_set_render_draw_color) {
zval *ren_res;
SDL_Renderer *ren;
zend_long r, g, b, a;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "rllll", &ren_res, &r, &g, &b, &a) == FAILURE) {
RETURN_THROWS();
}
ren = (SDL_Renderer *)zend_fetch_resource(Z_RES_P(ren_res), "SDL_Renderer", le_sdl_renderer);
if (!ren) {
RETURN_FALSE;
}
SDL_SetRenderDrawColor(ren, (Uint8)r, (Uint8)g, (Uint8)b, (Uint8)a);
RETURN_TRUE;
}
PHP_FUNCTION(sdl_render_clear) {
zval *ren_res;
SDL_Renderer *ren;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &ren_res) == FAILURE) {
RETURN_THROWS();
}
ren = (SDL_Renderer *)zend_fetch_resource(Z_RES_P(ren_res), "SDL_Renderer", le_sdl_renderer);
if (!ren) {
RETURN_FALSE;
}
SDL_RenderClear(ren);
RETURN_TRUE;
}
PHP_FUNCTION(sdl_render_fill_rect) {
zval *ren_res;
SDL_Renderer *ren;
zval *rect_arr;
HashTable *rect_ht;
zval *data;
zend_long x, y, w, h;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "ra", &ren_res, &rect_arr) == FAILURE) {
RETURN_THROWS();
}
ren = (SDL_Renderer *)zend_fetch_resource(Z_RES_P(ren_res), "SDL_Renderer", le_sdl_renderer);
if (!ren) {
RETURN_FALSE;
}
rect_ht = Z_ARRVAL_P(rect_arr);
if (((data = zend_hash_str_find(rect_ht, "x", 1)) != NULL && (x = zval_get_long(data), true)) &&
((data = zend_hash_str_find(rect_ht, "y", 1)) != NULL && (y = zval_get_long(data), true)) &&
((data = zend_hash_str_find(rect_ht, "w", 1)) != NULL && (w = zval_get_long(data), true)) &&
((data = zend_hash_str_find(rect_ht, "h", 1)) != NULL && (h = zval_get_long(data), true))) {
SDL_FRect rect = {(float)x, (float)y, (float)w, (float)h};
SDL_RenderFillRect(ren, &rect);
RETURN_TRUE;
}
zend_throw_error(NULL, "Invalid rectangle array passed to sdl_render_fill_rect. Expected ['x'=>int, 'y'=>int, 'w'=>int, 'h'=>int]");
RETURN_THROWS();
}
PHP_FUNCTION(sdl_render_present) {
zval *ren_res;
SDL_Renderer *ren;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &ren_res) == FAILURE) {
RETURN_THROWS();
}
ren = (SDL_Renderer *)zend_fetch_resource(Z_RES_P(ren_res), "SDL_Renderer", le_sdl_renderer);
if (!ren) {
RETURN_FALSE;
}
SDL_RenderPresent(ren);
RETURN_TRUE;
}
PHP_FUNCTION(sdl_delay) {
zend_long ms;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &ms) == FAILURE) {
RETURN_THROWS();
}
SDL_Delay((Uint32)ms);
}
PHP_FUNCTION(sdl_get_error) {
const char *error = SDL_GetError();
RETURN_STRING(error);
}
PHP_FUNCTION(sdl_rounded_box)
{
zval *ren_res;
SDL_Renderer *ren;
zend_long x1, y1, x2, y2, rad;
zend_long r, g, b, a;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "rlllllllll", &ren_res, &x1, &y1, &x2, &y2, &rad, &r, &g, &b, &a) == FAILURE) {
RETURN_THROWS();
}
ren = (SDL_Renderer *)zend_fetch_resource(Z_RES_P(ren_res), "SDL_Renderer", le_sdl_renderer);
if (!ren) {
RETURN_FALSE;
}
if (roundedBoxRGBA(ren, (Sint16)x1, (Sint16)y1, (Sint16)x2, (Sint16)y2, (Sint16)rad, (Uint8)r, (Uint8)g, (Uint8)b, (Uint8)a) == 0) {
RETURN_TRUE;
}
RETURN_FALSE;
}
#include <math.h>
PHP_FUNCTION(sdl_rounded_box_ex)
{
zval *ren_res;
SDL_Renderer *ren;
zend_long x1, y1, x2, y2;
zend_long rad_tl, rad_tr, rad_br, rad_bl;
zend_long r, g, b, a;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "rllllllllllll", &ren_res, &x1, &y1, &x2, &y2, &rad_tl, &rad_tr, &rad_br, &rad_bl, &r, &g, &b, &a) == FAILURE) {
RETURN_THROWS();
}
ren = (SDL_Renderer *)zend_fetch_resource(Z_RES_P(ren_res), "SDL_Renderer", le_sdl_renderer);
if (!ren) RETURN_FALSE;
SDL_SetRenderDrawColor(ren, r, g, b, a);
int halfw = ((Sint16)x2-(Sint16)x1) / 2;
int halfh = ((Sint16)y2-(Sint16)y1) / 2;
if (rad_tl > halfw) rad_tl = halfw; if (rad_tl > halfh) rad_tl = halfh;
if (rad_tr > halfw) rad_tr = halfw; if (rad_tr > halfh) rad_tr = halfh;
if (rad_br > halfw) rad_br = halfw; if (rad_br > halfh) rad_br = halfh;
if (rad_bl > halfw) rad_bl = halfw; if (rad_bl > halfh) rad_bl = halfh;
int r_left = (rad_tl > rad_bl) ? rad_tl : rad_bl;
int r_right = (rad_tr > rad_br) ? rad_tr : rad_br;
// 1) center vertical band (zwischen links und rechts Radien), ganze Höhe
SDL_FRect center = { x1 + rad_tl, y1, x2 - x1-rad_tl-rad_br, y2-y1 };
if (center.w > 0 && center.h > 0) SDL_RenderFillRect(ren, &center);
// 2) left vertical rectangle (zwischen oberen und unteren Ecken links)
SDL_FRect leftRect = { x1, y1 + rad_tl, rad_bl, y2-rad_tl-rad_bl-y1 };
if (leftRect.w > 0 && leftRect.h > 0) SDL_RenderFillRect(ren, &leftRect);
// 3) right vertical rectangle (zwischen oberen und unteren Ecken rechts)
SDL_FRect rightRect = { x2 - r_right, y1 + rad_tr, r_right, y2-y1-rad_tr - rad_br };
if (rightRect.w > 0 && rightRect.h > 0) SDL_RenderFillRect(ren, &rightRect);
// 4) vier gefüllte Viertel-Kreise in den Ecken
if (rad_tl > 0) filled_quarter_circle(ren, x1 + rad_tl, y1 + rad_tl, rad_tl, 0);
if (rad_tr > 0) filled_quarter_circle(ren, x2 - rad_tr, y1 + rad_tr, rad_tr, 1);
if (rad_br > 0) filled_quarter_circle(ren, x2 - rad_br, y2- rad_br, rad_br, 2);
if (rad_bl > 0) filled_quarter_circle(ren, x1 + rad_bl, y2 - rad_bl, rad_bl, 3);
RETURN_TRUE;
}
ZEND_BEGIN_ARG_INFO_EX(arginfo_sdl_init, 0, 0, 1)
ZEND_ARG_INFO(0, flags)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(arginfo_sdl_quit, 0, 0, 0)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(arginfo_sdl_create_window, 0, 0, 3)
ZEND_ARG_INFO(0, title)
ZEND_ARG_INFO(0, w)
ZEND_ARG_INFO(0, h)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(arginfo_sdl_create_renderer, 0, 0, 1)
ZEND_ARG_INFO(0, window)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(arginfo_sdl_set_render_draw_color, 0, 0, 5)
ZEND_ARG_INFO(0, renderer)
ZEND_ARG_INFO(0, r)
ZEND_ARG_INFO(0, g)
ZEND_ARG_INFO(0, b)
ZEND_ARG_INFO(0, a)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(arginfo_sdl_render_clear, 0, 0, 1)
ZEND_ARG_INFO(0, renderer)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(arginfo_sdl_render_fill_rect, 0, 0, 2)
ZEND_ARG_INFO(0, renderer)
ZEND_ARG_INFO(0, rect)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(arginfo_sdl_render_present, 0, 0, 1)
ZEND_ARG_INFO(0, renderer)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(arginfo_sdl_delay, 0, 0, 1)
ZEND_ARG_INFO(0, ms)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(arginfo_sdl_get_error, 0, 0, 0)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(arginfo_sdl_rounded_box, 0, 0, 10)
ZEND_ARG_INFO(0, renderer)
ZEND_ARG_INFO(0, x1)
ZEND_ARG_INFO(0, y1)
ZEND_ARG_INFO(0, x2)
ZEND_ARG_INFO(0, y2)
ZEND_ARG_INFO(0, radius)
ZEND_ARG_INFO(0, r)
ZEND_ARG_INFO(0, g)
ZEND_ARG_INFO(0, b)
ZEND_ARG_INFO(0, a)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(arginfo_sdl_rounded_box_ex, 0, 0, 13)
ZEND_ARG_INFO(0, renderer)
ZEND_ARG_INFO(0, x1)
ZEND_ARG_INFO(0, y1)
ZEND_ARG_INFO(0, x2)
ZEND_ARG_INFO(0, y2)
ZEND_ARG_INFO(0, rad_tl)
ZEND_ARG_INFO(0, rad_tr)
ZEND_ARG_INFO(0, rad_br)
ZEND_ARG_INFO(0, rad_bl)
ZEND_ARG_INFO(0, r)
ZEND_ARG_INFO(0, g)
ZEND_ARG_INFO(0, b)
ZEND_ARG_INFO(0, a)
ZEND_END_ARG_INFO()
const zend_function_entry sdl3_functions[] = {
PHP_FE(sdl_init, arginfo_sdl_init)
PHP_FE(sdl_quit, arginfo_sdl_quit)
PHP_FE(sdl_create_window, arginfo_sdl_create_window)
PHP_FE(sdl_create_renderer, arginfo_sdl_create_renderer)
PHP_FE(sdl_set_render_draw_color, arginfo_sdl_set_render_draw_color)
PHP_FE(sdl_render_clear, arginfo_sdl_render_clear)
PHP_FE(sdl_render_fill_rect, arginfo_sdl_render_fill_rect)
PHP_FE(sdl_render_present, arginfo_sdl_render_present)
PHP_FE(sdl_delay, arginfo_sdl_delay)
PHP_FE(sdl_get_error, arginfo_sdl_get_error)
PHP_FE(sdl_rounded_box, arginfo_sdl_rounded_box)
PHP_FE(sdl_rounded_box_ex, arginfo_sdl_rounded_box_ex)
PHP_FE_END
};
zend_module_entry sdl3_module_entry = {
STANDARD_MODULE_HEADER,
"sdl3",
sdl3_functions,
PHP_MINIT(sdl3),
NULL, // MSHUTDOWN
NULL, // RINIT
NULL, // RSHUTDOWN
NULL, // MINFO
PHP_SDL3_VERSION,
STANDARD_MODULE_PROPERTIES
};
#ifdef COMPILE_DL_SDL3
#ifdef ZTS
ZEND_TSRMLS_CACHE_DEFINE()
#endif
ZEND_GET_MODULE(sdl3)
#endif

94
php-sdl3/sdl3.dep Normal file
View File

@ -0,0 +1,94 @@
sdl3.lo: /home/thomas/projekte/phpnative/framework/php-sdl3/sdl3.c \
/home/thomas/projekte/phpnative/framework/php-sdl3/config.h \
/usr/local/include/php/main/php.h \
/usr/local/include/php/main/php_version.h \
/usr/local/include/php/Zend/zend.h \
/usr/local/include/php/Zend/zend_types.h \
/usr/local/include/php/Zend/zend_portability.h \
/usr/local/include/php/Zend/zend_config.h \
/usr/local/include/php/main/../main/php_config.h \
/usr/local/include/php/Zend/../TSRM/TSRM.h \
/usr/local/include/php/main/php_config.h \
/usr/local/include/php/Zend/zend_range_check.h \
/usr/local/include/php/Zend/zend_long.h \
/usr/local/include/php/Zend/zend_map_ptr.h \
/usr/local/include/php/Zend/zend_errors.h \
/usr/local/include/php/Zend/zend_alloc.h \
/usr/local/include/php/Zend/zend_alloc_sizes.h \
/usr/local/include/php/Zend/zend_llist.h \
/usr/local/include/php/Zend/zend_string.h \
/usr/local/include/php/Zend/zend_gc.h \
/usr/local/include/php/Zend/zend_hrtime.h \
/usr/local/include/php/Zend/zend_hash.h \
/usr/local/include/php/Zend/zend_sort.h \
/usr/local/include/php/Zend/zend_ast.h \
/usr/local/include/php/Zend/zend_variables.h \
/usr/local/include/php/Zend/zend_iterators.h \
/usr/local/include/php/Zend/zend_stream.h \
/usr/local/include/php/Zend/zend_smart_str_public.h \
/usr/local/include/php/Zend/zend_smart_string_public.h \
/usr/local/include/php/Zend/zend_signal.h \
/usr/local/include/php/Zend/zend_max_execution_timer.h \
/usr/local/include/php/Zend/zend_object_handlers.h \
/usr/local/include/php/Zend/zend_property_hooks.h \
/usr/local/include/php/Zend/zend_lazy_objects.h \
/usr/local/include/php/Zend/zend_types.h \
/usr/local/include/php/Zend/zend_operators.h \
/usr/local/include/php/Zend/zend_strtod.h \
/usr/local/include/php/Zend/zend_multiply.h \
/usr/local/include/php/Zend/zend_sort.h \
/usr/local/include/php/main/php_compat.h \
/usr/local/include/php/main/php_config.h \
/usr/local/include/php/Zend/zend_API.h \
/usr/local/include/php/Zend/zend_modules.h \
/usr/local/include/php/Zend/zend.h \
/usr/local/include/php/Zend/zend_compile.h \
/usr/local/include/php/Zend/zend_frameless_function.h \
/usr/local/include/php/Zend/zend_globals.h \
/usr/local/include/php/Zend/zend_globals_macros.h \
/usr/local/include/php/Zend/zend_atomic.h \
/usr/local/include/php/Zend/zend_stack.h \
/usr/local/include/php/Zend/zend_ptr_stack.h \
/usr/local/include/php/Zend/zend_objects.h \
/usr/local/include/php/Zend/zend_objects_API.h \
/usr/local/include/php/Zend/zend_float.h \
/usr/local/include/php/Zend/zend_multibyte.h \
/usr/local/include/php/Zend/zend_arena.h \
/usr/local/include/php/Zend/zend_call_stack.h \
/usr/local/include/php/Zend/zend_vm_opcodes.h \
/usr/local/include/php/Zend/zend_build.h \
/usr/local/include/php/Zend/zend_list.h \
/usr/local/include/php/Zend/zend_execute.h \
/usr/local/include/php/Zend/zend_type_info.h \
/usr/local/include/php/main/build-defs.h \
/usr/local/include/php/Zend/zend_hash.h \
/usr/local/include/php/Zend/zend_alloc.h \
/usr/local/include/php/Zend/zend_stack.h \
/usr/local/include/php/main/snprintf.h \
/usr/local/include/php/main/spprintf.h \
/usr/local/include/php/Zend/zend_smart_str_public.h \
/usr/local/include/php/Zend/zend_smart_string_public.h \
/usr/local/include/php/main/php_syslog.h \
/usr/local/include/php/main/php.h \
/usr/local/include/php/main/php_output.h \
/usr/local/include/php/main/php_streams.h \
/usr/local/include/php/Zend/zend_stream.h \
/usr/local/include/php/main/streams/php_stream_context.h \
/usr/local/include/php/main/streams/php_stream_filter_api.h \
/usr/local/include/php/main/streams/php_stream_transport.h \
/usr/local/include/php/main/streams/php_stream_plain_wrapper.h \
/usr/local/include/php/main/streams/php_stream_glob_wrapper.h \
/usr/local/include/php/main/streams/php_stream_userspace.h \
/usr/local/include/php/main/streams/php_stream_mmap.h \
/usr/local/include/php/main/php_memory_streams.h \
/usr/local/include/php/main/fopen_wrappers.h \
/usr/local/include/php/main/php_globals.h \
/usr/local/include/php/Zend/zend_globals.h \
/usr/local/include/php/main/php_ini.h \
/usr/local/include/php/Zend/zend_ini.h \
/usr/local/include/php/Zend/zend_virtual_cwd.h \
/usr/local/include/php/TSRM/TSRM.h \
/usr/local/include/php/Zend/zend_constants.h \
/usr/local/include/php/main/php_reentrancy.h \
/home/thomas/projekte/phpnative/framework/php-sdl3/php_sdl3.h \
/home/thomas/projekte/phpnative/framework/php-sdl3/helper.h

35
php-sdl3/sdl3.la Normal file
View File

@ -0,0 +1,35 @@
# sdl3.la - a libtool library file
# Generated by ltmain.sh - GNU libtool 1.5.26 (1.1220.2.492 2008/01/30 06:40:56)
#
# Please DO NOT delete this file!
# It is necessary for linking the library.
# The name that we can dlopen(3).
dlname='sdl3.so'
# Names of this library.
library_names='sdl3.so sdl3.so sdl3.so'
# The name of the static archive.
old_library=''
# Libraries that this one depends upon.
dependency_libs=' -L/usr/local/lib -lSDL3_gfx -lSDL3'
# Version information for sdl3.
current=0
age=0
revision=0
# Is this an already installed library?
installed=no
# Should we warn about portability when linking against -modules?
shouldnotlink=yes
# Files to dlopen/dlpreopen
dlopen=''
dlpreopen=''
# Directory that this library needs to be installed in:
libdir='/home/thomas/projekte/phpnative/framework/php-sdl3/modules'

12
php-sdl3/sdl3.lo Normal file
View File

@ -0,0 +1,12 @@
# sdl3.lo - a libtool object file
# Generated by ltmain.sh - GNU libtool 1.5.26 (1.1220.2.492 2008/01/30 06:40:56)
#
# Please DO NOT delete this file!
# It is necessary for linking the library.
# Name of the PIC object.
pic_object='.libs/sdl3.o'
# Name of the non-PIC object.
non_pic_object=none

27
php-sdl3/test.php Normal file
View File

@ -0,0 +1,27 @@
<?php
if (!extension_loaded('sdl3')) {
echo "Die Erweiterung 'sdl3' ist nicht geladen.\n";
// Optional: Versuch, sie dynamisch zu laden (funktioniert möglicherweise nicht in allen Umgebungen)
if (function_exists('dl')) {
if (!@dl('sdl3.so')) {
echo "Konnte die Erweiterung nicht dynamisch laden.\n";
exit(1);
}
} else {
exit(1);
}
}
echo "Die Erweiterung 'sdl3' ist geladen.\n";
if (function_exists('confirm_sdl3_compiled')) {
echo "Funktion 'confirm_sdl3_compiled()' existiert.\n";
$result = confirm_sdl3_compiled();
echo "Ergebnis: ";
var_dump($result);
} else {
echo "FEHLER: Funktion 'confirm_sdl3_compiled()' existiert nicht!\n";
}
?>

View File

@ -71,9 +71,10 @@ class Application
while ($this->running && count($this->windows) > 0) {
// Layout all windows FIRST (sets window references and calculates positions)
foreach ($this->windows as $windowId => $window) {
$window->layout();
if ($window->layout()) {
echo 'Layoutout: ' . PHP_EOL;
}
}
// Poll events globally for all windows (event queue mode, if available)
rgfw_pollEvents();
@ -85,13 +86,7 @@ class Application
// Update async tasks (global)
TaskManager::getInstance()->update();
// Update all windows
foreach ($this->windows as $windowId => $window) {
if (!$window->shouldClose()) {
$window->update();
}
}
// Update all windows and their hover states
// Render all windows (skip windows that are closing)
foreach ($this->windows as $windowId => $window) {
if (!$window->shouldClose()) {
@ -99,11 +94,20 @@ class Application
}
}
$oneWindowIsClosed = false;
// Remove closed windows
foreach ($this->windows as $windowId => $window) {
if ($window->shouldClose()) {
$window->cleanup();
$window->cleanup(); // Frees the TextRenderer to prevent "fat text" bug
rgfw_window_close($window->getWindowResource()); // Now, safely close the native window
unset($this->windows[$windowId]);
$oneWindowIsClosed = true;
}
}
if ($oneWindowIsClosed) {
foreach ($this->windows as $windowId => $window) {
$window->setShouldBeReLayouted(true);
}
}

View File

@ -6,6 +6,7 @@ use PHPNative\Framework\TextRenderer;
use PHPNative\Tailwind\Style\Margin;
use PHPNative\Tailwind\Style\MediaQueryEnum;
use PHPNative\Tailwind\Style\Padding;
use PHPNative\Tailwind\Style\State;
use PHPNative\Tailwind\Style\StateEnum;
use PHPNative\Tailwind\StyleParser;
@ -13,7 +14,6 @@ abstract class Component
{
protected $children = [];
protected $window;
protected $pixelRatio;
protected bool $visible = true;
@ -66,16 +66,6 @@ abstract class Component
}
}
public function setWindow($window): void
{
$this->window = $window;
// Recursively set window for all children
foreach ($this->children as $child) {
$child->setWindow($window);
}
}
public function setPixelRatio($pixelRatio): void
{
$this->pixelRatio = $pixelRatio;
@ -111,7 +101,7 @@ abstract class Component
}
}
public function render(null|TextRenderer $textRenderer = null): void
public function render(&$window, null|TextRenderer $textRenderer = null): void
{
if (!$this->visible) {
return;
@ -121,14 +111,18 @@ abstract class Component
isset($this->computedStyles[\PHPNative\Tailwind\Style\Background::class]) &&
($bg = $this->computedStyles[\PHPNative\Tailwind\Style\Background::class])
) {
rsgl_setColor($this->window, $bg->color->red, $bg->color->green, $bg->color->blue, $bg->color->alpha);
if ($this->currentState == StateEnum::hover) {
rsgl_setColor($window, $bg->color->red, $bg->color->green, $bg->color->blue, 10);
} else {
rsgl_setColor($window, $bg->color->red, $bg->color->green, $bg->color->blue, $bg->color->alpha);
}
if (
isset($this->computedStyles[\PHPNative\Tailwind\Style\Border::class]) &&
($border = $this->computedStyles[\PHPNative\Tailwind\Style\Border::class])
) {
rsgl_drawRoundRectExF(
$this->window,
$window,
$this->viewport->x,
$this->viewport->y,
$this->viewport->width,
@ -144,7 +138,7 @@ abstract class Component
);
} else {
rsgl_drawRectF(
$this->window,
$window,
$this->viewport->x,
$this->viewport->y,
$this->viewport->width,
@ -154,7 +148,7 @@ abstract class Component
}
}
public function renderContent(null|TextRenderer $textRenderer = null): void
public function renderContent(&$window, null|TextRenderer $textRenderer = null): void
{
if (!$this->visible) {
return;
@ -162,9 +156,8 @@ abstract class Component
// Render children
foreach ($this->children as $child) {
$child->setWindow($this->window);
$child->render($textRenderer);
$child->renderContent($textRenderer);
$child->render($window, $textRenderer);
$child->renderContent($window, $textRenderer);
}
}
@ -211,8 +204,6 @@ abstract class Component
$this->currentState,
);
}
// Propagate to children
foreach ($this->children as $child) {
$child->handleMouseMove($mouseX, $mouseY);
}

View File

@ -309,7 +309,7 @@ class Container extends Component
];
}
public function renderContent(null|TextRenderer $textRenderer = null): void
public function renderContent(&$window, null|TextRenderer $textRenderer = null): void
{
if (!$this->visible) {
return;
@ -332,18 +332,16 @@ class Container extends Component
// We need to flush the batch before/after scissor to ensure correct clipping
// Step 1: Flush any pending draw calls before scissor
rsgl_render($this->window);
rsgl_render($window);
// Step 2: Enable scissor test for clipping
$windowHeight = $this->contentViewport->windowHeight;
$invertedY = $windowHeight - ($scissorY + $scissorH);
rsgl_scissorStart($this->window, $scissorX, $invertedY, $scissorW, $scissorH);
rsgl_scissorStart($window, $scissorX, $invertedY, $scissorW, $scissorH);
// Step 3: Render children with scroll offset (batches draw calls)
foreach ($this->children as $child) {
$child->setWindow($this->window);
// Apply scroll offset recursively to child and all its descendants
$child->applyScrollOffset((int) $this->scrollX, (int) $this->scrollY);
@ -366,16 +364,16 @@ class Container extends Component
}
// Step 4: Flush the batch while scissor is still active
rsgl_render($this->window);
rsgl_render($window);
// Step 5: Disable scissor test
rsgl_scissorEnd($this->window);
rsgl_scissorEnd($window);
// Render scrollbars
$this->renderScrollbars($overflow);
} else {
// No overflow, render normally
parent::renderContent($textRenderer);
parent::renderContent($window, $textRenderer);
}
}
@ -503,8 +501,8 @@ class Container extends Component
// Propagate to children if not on scrollbar
// Only adjust coordinates if we have active scrolling
$adjustedMouseX = $overflow['x'] || $overflow['y'] ? $mouseX + $this->scrollX : $mouseX;
$adjustedMouseY = $overflow['x'] || $overflow['y'] ? $mouseY + $this->scrollY : $mouseY;
$adjustedMouseX = $overflow['x'] || $overflow['y'] ? ($mouseX + $this->scrollX) : $mouseX;
$adjustedMouseY = $overflow['x'] || $overflow['y'] ? ($mouseY + $this->scrollY) : $mouseY;
foreach ($this->children as $child) {
if (method_exists($child, 'handleMouseClick')) {
@ -548,8 +546,8 @@ class Container extends Component
}
// Propagate to children - only adjust coordinates if we have active scrolling
$adjustedMouseX = $overflow['x'] || $overflow['y'] ? $mouseX + $this->scrollX : $mouseX;
$adjustedMouseY = $overflow['x'] || $overflow['y'] ? $mouseY + $this->scrollY : $mouseY;
$adjustedMouseX = $overflow['x'] || $overflow['y'] ? ($mouseX + $this->scrollX) : $mouseX;
$adjustedMouseY = $overflow['x'] || $overflow['y'] ? ($mouseY + $this->scrollY) : $mouseY;
foreach ($this->children as $child) {
if (method_exists($child, 'handleMouseMove')) {
@ -565,8 +563,8 @@ class Container extends Component
// Propagate to children - only adjust coordinates if we have active scrolling
$overflow = $this->hasOverflow();
$adjustedMouseX = $overflow['x'] || $overflow['y'] ? $mouseX + $this->scrollX : $mouseX;
$adjustedMouseY = $overflow['x'] || $overflow['y'] ? $mouseY + $this->scrollY : $mouseY;
$adjustedMouseX = $overflow['x'] || $overflow['y'] ? ($mouseX + $this->scrollX) : $mouseX;
$adjustedMouseY = $overflow['x'] || $overflow['y'] ? ($mouseY + $this->scrollY) : $mouseY;
foreach ($this->children as $child) {
if (method_exists($child, 'handleMouseRelease')) {
@ -600,8 +598,8 @@ class Container extends Component
}
// Propagate to children - only adjust coordinates if we have active scrolling
$adjustedMouseX = $overflow['x'] || $overflow['y'] ? $mouseX + $this->scrollX : $mouseX;
$adjustedMouseY = $overflow['x'] || $overflow['y'] ? $mouseY + $this->scrollY : $mouseY;
$adjustedMouseX = $overflow['x'] || $overflow['y'] ? ($mouseX + $this->scrollX) : $mouseX;
$adjustedMouseY = $overflow['x'] || $overflow['y'] ? ($mouseY + $this->scrollY) : $mouseY;
foreach ($this->children as $child) {
if (method_exists($child, 'handleMouseWheel')) {

View File

@ -43,7 +43,7 @@ class Label extends Component
}
}
public function renderContent(null|TextRenderer $textRenderer = null): void
public function renderContent(&$window, null|TextRenderer $textRenderer = null): void
{
if (!$this->visible || $textRenderer === null || !$textRenderer->isInitialized()) {
return;
@ -64,6 +64,6 @@ class Label extends Component
$textRenderer->drawText($this->text, (int) $x, (int) $y, $textStyle->size);
// Call parent to render children if any
parent::renderContent($textRenderer);
parent::renderContent($window, $textRenderer);
}
}

View File

@ -8,7 +8,7 @@ class Window
{
private mixed $window = null;
private null|Component $rootComponent = null;
private TextRenderer $textRenderer;
private ?TextRenderer $textRenderer;
private float $mouseX = 0;
private float $mouseY = 0;
private Viewport $viewport;
@ -106,14 +106,7 @@ class Window
*/
public function handleEvents(): void
{
// Limit events processed per frame to prevent one window from blocking others
// This is especially important in multi-window scenarios
$maxEventsPerFrame = 20;
$eventsProcessed = 0;
while ($event = rgfw_window_checkQueuedEvent($this->window)) {
$eventsProcessed++;
// Debug output - can be removed later
if (defined('DEBUG_EVENTS') && DEBUG_EVENTS) {
$eventTypes = [
@ -203,22 +196,49 @@ class Window
}
}
/**
* Update mouse position and hover states
* This is called every frame to ensure hover works even without focus
*/
public function updateMousePosition(): void
{
if (!$this->rootComponent) {
return;
}
// Try to get current mouse position relative to this window
if (function_exists('rgfw_window_getMousePoint')) {
$mousePos = rgfw_window_getMousePoint($this->window);
if ($mousePos !== false && is_array($mousePos)) {
$newX = $mousePos[0] ?? $this->mouseX;
$newY = $mousePos[1] ?? $this->mouseY;
// Only update if position changed to avoid unnecessary updates
if ($newX !== $this->mouseX || $newY !== $this->mouseY) {
$this->mouseX = $newX;
$this->mouseY = $newY;
$this->rootComponent->handleMouseMove($this->mouseX, $this->mouseY);
}
}
} else {
// rgfw_window_getMousePoint() not available
// Hover will only work when window receives mouse events
// This is normal OS behavior - only focused windows get mouse events
static $warningShown = false;
if (!$warningShown && defined('DEBUG_EVENTS') && DEBUG_EVENTS) {
error_log(
'Note: rgfw_window_getMousePoint() not available. Hover states will only work for focused windows.',
);
$warningShown = true;
}
}
}
/**
* Update window state
*/
public function update(): void
{
// Update hover states based on current mouse position
// This ensures hover works even when the window doesn't have focus
if ($this->rootComponent && function_exists('rgfw_window_getMousePoint')) {
$mousePos = rgfw_window_getMousePoint($this->window);
if ($mousePos !== false) {
$this->mouseX = $mousePos[0] ?? $this->mouseX;
$this->mouseY = $mousePos[1] ?? $this->mouseY;
$this->rootComponent->handleMouseMove($this->mouseX, $this->mouseY);
}
}
if ($this->rootComponent) {
$this->rootComponent->update();
}
@ -227,17 +247,18 @@ class Window
/**
* Layout components
*/
public function layout(): void
public function layout(): bool
{
if ($this->rootComponent) {
if ($this->rootComponent && $this->shouldBeReLayouted) {
// Always layout for now - we can optimize this later by tracking what changed
// The shouldBeReLayouted flag was preventing proper layout updates
$this->rootComponent->setViewport($this->viewport);
$this->rootComponent->setWindow($this->window);
$this->rootComponent->layout($this->textRenderer);
$this->shouldBeReLayouted = false;
$this->hasBeenLaidOut = true;
return true;
}
return false;
}
/**
@ -246,18 +267,19 @@ class Window
public function render(): void
{
// Always clear the window to prevent black screens (white background, fully opaque)
rsgl_clear($this->window, 255, 255, 255, 255);
// Only render content if window has been laid out
// This can happen when windows are created during async callbacks
if ($this->hasBeenLaidOut && $this->rootComponent) {
$this->rootComponent->render($this->textRenderer);
$this->rootComponent->renderContent($this->textRenderer);
rgfw_window_makeCurrent($this->window);
rsgl_clear($this->window, 255, 255, 255, 255);
$this->rootComponent->render($this->window, $this->textRenderer);
$this->rootComponent->renderContent($this->window, $this->textRenderer);
rsgl_render($this->window);
rgfw_window_swapBuffers($this->window);
}
// Always swap buffers to display the cleared window
rsgl_render($this->window);
rgfw_window_swapBuffers($this->window);
}
/**
@ -267,8 +289,12 @@ class Window
{
if ($this->textRenderer) {
$this->textRenderer->free();
$this->textRenderer = null; // Prevent destructor from running again
}
rsgl_close($this->window);
rgfw_window_close($this->window);
}
public function setShouldBeReLayouted(bool $shouldBeReLayouted): void
{
$this->shouldBeReLayouted = $shouldBeReLayouted;
}
}