remove system configuration syscalls

This commit is contained in:
nakst 2021-08-23 11:52:34 +01:00
parent 676162a438
commit 67323075f5
11 changed files with 121 additions and 138 deletions

View File

@ -2,6 +2,7 @@
name=File Manager
icon=icon_system_file_manager
permission_all_files=1
permission_view_file_types=1
use_single_process=1
[build]
@ -31,11 +32,13 @@ icon=icon_application_x_ms_dos_executable
extension=png
name=PNG image
icon=icon_image_x_generic
has_thumbnail_generator=1
[@file_type]
extension=jpg
name=JPG image
icon=icon_image_x_generic
has_thumbnail_generator=1
[@file_type]
extension=ttf
@ -111,4 +114,3 @@ icon=icon_view_list_video_symbolic
extension=wav
name=Wave audio
icon=icon_audio_x_generic
ES_ICON_AUDIO_X_GENERIC

View File

@ -1,6 +1,8 @@
struct FileType {
char *name;
size_t nameBytes;
char *extension;
size_t extensionBytes;
uint32_t iconID;
int64_t openHandler;
@ -16,6 +18,9 @@ void AddKnownFileTypes() {
{ \
FileType type = {}; \
type.name = (char *) _name; \
type.nameBytes = EsCStringLength(_name); \
type.extension = (char *) _extension; \
type.extensionBytes = EsCStringLength(_extension); \
type.iconID = _iconID; \
uintptr_t index = knownFileTypes.Length(); \
knownFileTypes.Add(type); \
@ -37,39 +42,31 @@ void AddKnownFileTypes() {
#define KNOWN_FILE_TYPE_DRIVES_PAGE (6)
ADD_FILE_TYPE("", interfaceString_FileManagerDrivesPage, ES_ICON_COMPUTER_LAPTOP);
size_t groupCount;
EsSystemConfigurationGroup *groups = EsSystemConfigurationReadAll(&groupCount);
for (uintptr_t i = 0; i < groupCount; i++) {
EsSystemConfigurationGroup *group = groups + i;
if (EsStringCompareRaw(group->sectionClass, group->sectionClassBytes, EsLiteral("file_type"))) {
continue;
}
FileType type = {};
type.name = EsSystemConfigurationGroupReadString(group, "name", -1, &type.nameBytes);
type.openHandler = EsSystemConfigurationGroupReadInteger(group, "open", -1);
char *iconName = EsSystemConfigurationGroupReadString(group, "icon", -1);
if (iconName) {
type.iconID = EsIconIDFromString(iconName);
EsHeapFree(iconName);
}
char *extension = EsSystemConfigurationGroupReadString(group, "extension", -1);
// TODO Proper thumbnail generator registrations.
if (0 == EsCRTstrcmp(extension, "jpg") || 0 == EsCRTstrcmp(extension, "png") || 0 == EsCRTstrcmp(extension, "bmp")) {
EsBuffer buffer = { .canGrow = true };
EsSystemConfigurationReadFileTypes(&buffer);
EsINIState s = { .buffer = (char *) buffer.out, .bytes = buffer.bytes };
FileType type = {};
while (EsINIParse(&s)) {
if (0 == EsStringCompareRaw(s.key, s.keyBytes, EsLiteral("name"))) {
type.name = s.value, type.nameBytes = s.valueBytes;
} else if (0 == EsStringCompareRaw(s.key, s.keyBytes, EsLiteral("extension"))) {
type.extension = s.value, type.extensionBytes = s.valueBytes;
} else if (0 == EsStringCompareRaw(s.key, s.keyBytes, EsLiteral("open"))) {
type.openHandler = EsIntegerParse(s.value, s.valueBytes);
} else if (0 == EsStringCompareRaw(s.key, s.keyBytes, EsLiteral("icon"))) {
type.iconID = EsIconIDFromString(s.value, s.valueBytes);
} else if (0 == EsStringCompareRaw(s.key, s.keyBytes, EsLiteral("has_thumbnail_generator")) && EsIntegerParse(s.value, s.valueBytes)) {
// TODO Proper thumbnail generator registrations.
type.hasThumbnailGenerator = true;
}
uintptr_t index = knownFileTypes.Length();
knownFileTypes.Add(type);
*knownFileTypesByExtension.Put(extension, EsCStringLength(extension)) = index;
if (!EsINIPeek(&s) || !s.keyBytes) {
uintptr_t index = knownFileTypes.Length();
knownFileTypes.Add(type);
*knownFileTypesByExtension.Put(type.extension, type.extensionBytes) = index;
EsMemoryZero(&type, sizeof(type));
}
}
}

View File

@ -700,7 +700,7 @@ int ListCallback(EsElement *element, EsMessage *message) {
EsBufferFormat(message->getContent.buffer, "%s", name.bytes, name.text);
message->getContent.icon = fileType->iconID;
} else if (column == COLUMN_TYPE) {
EsBufferFormat(message->getContent.buffer, "%z", fileType->name);
EsBufferFormat(message->getContent.buffer, "%s", fileType->nameBytes, fileType->name);
} else if (column == COLUMN_SIZE) {
if (!entry->sizeUnknown) {
EsBufferFormat(message->getContent.buffer, "%D", entry->size);
@ -713,7 +713,7 @@ int ListCallback(EsElement *element, EsMessage *message) {
FolderEntry *entry = listEntry->entry;
FileType *fileType = FolderEntryGetType(instance->folder, entry);
String name = entry->GetName();
EsBufferFormat(message->getContent.buffer, "%s\n\a2]%z " HYPHENATION_POINT " %D", name.bytes, name.text, fileType->name, entry->size);
EsBufferFormat(message->getContent.buffer, "%s\n\a2]%s " HYPHENATION_POINT " %D", name.bytes, name.text, fileType->nameBytes, fileType->name, entry->size);
message->getContent.icon = fileType->iconID;
message->getContent.richText = true;
} else if (message->type == ES_MSG_LIST_VIEW_SELECT_RANGE) {

View File

@ -356,7 +356,7 @@ void AddListView(EsListView **pointer, EsElement *switcher, EsUICallbackFunction
void TerminateProcess(Instance *instance, EsElement *, EsCommand *) {
if (selectedPID == 0 /* Kernel */) {
// Terminating the kernel process is a meaningless action; the closest equivalent is shutting down.
EsSystemShowShutdownDialog(instance);
EsSystemShowShutdownDialog();
return;
}

View File

@ -59,6 +59,8 @@ struct EnumString { const char *cName; int value; };
#define DESKTOP_MSG_CREATE_CLIPBOARD_FILE (10)
#define DESKTOP_MSG_CLIPBOARD_PUT (11)
#define DESKTOP_MSG_CLIPBOARD_GET (12)
#define DESKTOP_MSG_SYSTEM_CONFIGURATION_GET (13)
#define DESKTOP_MSG_FILE_TYPES_GET (14)
extern "C" uintptr_t ProcessorTLSRead(uintptr_t offset);
@ -108,6 +110,7 @@ EsError NodeOpen(const char *path, size_t pathBytes, uint32_t flags, _EsNodeInfo
struct {
Array<EsSystemConfigurationGroup> systemConfigurationGroups;
EsMutex systemConfigurationMutex;
Array<MountPoint> mountPoints;
bool foundBootFileSystem;
EsProcessStartupInformation *startupInformation;
@ -279,7 +282,7 @@ EsSystemConfigurationGroup *SystemConfigurationGetGroup(const char *section, ptr
return nullptr;
}
char *EsSystemConfigurationGroupReadString(EsSystemConfigurationGroup *group, const char *key, ptrdiff_t keyBytes, size_t *valueBytes) {
char *EsSystemConfigurationGroupReadString(EsSystemConfigurationGroup *group, const char *key, ptrdiff_t keyBytes, size_t *valueBytes = nullptr) {
EsSystemConfigurationItem *item = SystemConfigurationGetItem(group, key, keyBytes);
if (!item) { if (valueBytes) *valueBytes = 0; return nullptr; }
if (valueBytes) *valueBytes = item->valueBytes;
@ -289,19 +292,23 @@ char *EsSystemConfigurationGroupReadString(EsSystemConfigurationGroup *group, co
return copy;
}
int64_t EsSystemConfigurationGroupReadInteger(EsSystemConfigurationGroup *group, const char *key, ptrdiff_t keyBytes, int64_t defaultValue) {
int64_t EsSystemConfigurationGroupReadInteger(EsSystemConfigurationGroup *group, const char *key, ptrdiff_t keyBytes, int64_t defaultValue = 0) {
EsSystemConfigurationItem *item = SystemConfigurationGetItem(group, key, keyBytes);
if (!item) return defaultValue;
return EsIntegerParse(item->value, item->valueBytes);
}
char *EsSystemConfigurationReadString(const char *section, ptrdiff_t sectionBytes, const char *key, ptrdiff_t keyBytes, size_t *valueBytes) {
EsMutexAcquire(&api.systemConfigurationMutex);
EsDefer(EsMutexRelease(&api.systemConfigurationMutex));
EsSystemConfigurationGroup *group = SystemConfigurationGetGroup(section, sectionBytes);
if (!group) { if (valueBytes) *valueBytes = 0; return nullptr; }
return EsSystemConfigurationGroupReadString(group, key, keyBytes, valueBytes);
}
int64_t EsSystemConfigurationReadInteger(const char *section, ptrdiff_t sectionBytes, const char *key, ptrdiff_t keyBytes, int64_t defaultValue) {
EsMutexAcquire(&api.systemConfigurationMutex);
EsDefer(EsMutexRelease(&api.systemConfigurationMutex));
EsSystemConfigurationGroup *group = SystemConfigurationGetGroup(section, sectionBytes);
if (!group) return defaultValue;
return EsSystemConfigurationGroupReadInteger(group, key, keyBytes, defaultValue);
@ -340,12 +347,6 @@ void SystemConfigurationLoad(char *file, size_t fileBytes) {
EsHeapFree(file);
}
EsSystemConfigurationGroup *EsSystemConfigurationReadAll(size_t *groupCount) {
EsMessageMutexCheck();
*groupCount = api.systemConfigurationGroups.Length();
return api.systemConfigurationGroups.array;
}
uint8_t *ApplicationStartupInformationToBuffer(const EsApplicationStartupInformation *information, size_t *dataBytes = nullptr) {
EsApplicationStartupInformation copy = *information;
if (copy.filePathBytes == -1) copy.filePathBytes = EsCStringLength(copy.filePath);
@ -503,9 +504,14 @@ void EsApplicationRunTemporary(EsInstance *instance, const char *path, ptrdiff_t
EsHeapFree(buffer);
}
void EsSystemShowShutdownDialog(EsInstance *instance) {
void EsSystemShowShutdownDialog() {
uint8_t message = DESKTOP_MSG_REQUEST_SHUTDOWN;
MessageDesktop(&message, 1, instance->window->handle);
MessageDesktop(&message, 1);
}
void EsSystemConfigurationReadFileTypes(EsBuffer *buffer) {
uint8_t m = DESKTOP_MSG_FILE_TYPES_GET;
MessageDesktop(&m, 1, ES_INVALID_HANDLE, buffer);
}
void InstanceSave(EsInstance *_instance) {
@ -1120,13 +1126,10 @@ extern "C" void _start(EsProcessStartupInformation *_startupInformation) {
EsHeapFree(initialMountPoints);
EsHandleClose(initialMountPointsBuffer);
size_t bytes;
EsHandle handle = EsSyscall(ES_SYSCALL_SYSTEM_CONFIGURATION_READ, 0, 0, (uintptr_t) &bytes, 0);
EsAssert(handle);
char *buffer = (char *) EsHeapAllocate(bytes, false);
EsConstantBufferRead(handle, buffer);
EsHandleClose(handle);
SystemConfigurationLoad(buffer, bytes);
uint8_t m = DESKTOP_MSG_SYSTEM_CONFIGURATION_GET;
EsBuffer responseBuffer = { .canGrow = true };
MessageDesktop(&m, 1, ES_INVALID_HANDLE, &responseBuffer);
SystemConfigurationLoad((char *) responseBuffer.in, responseBuffer.bytes);
}
if (uiProcess) {

View File

@ -39,6 +39,7 @@
#define APPLICATION_PERMISSION_POSIX_SUBSYSTEM (1 << 2)
#define APPLICATION_PERMISSION_RUN_TEMPORARY_APPLICATION (1 << 3)
#define APPLICATION_PERMISSION_SHUTDOWN (1 << 4)
#define APPLICATION_PERMISSION_VIEW_FILE_TYPES (1 << 5)
#define APPLICATION_ID_DESKTOP_BLANK_TAB (-1)
#define APPLICATION_ID_DESKTOP_SETTINGS (-2)
@ -1136,6 +1137,18 @@ void ApplicationInstanceCrashed(EsMessage *message) {
EsHandleClose(processHandle);
}
InstalledApplication *ApplicationFindByPID(EsObjectID pid) {
for (uintptr_t i = 0; i < desktop.allApplicationInstances.Length(); i++) {
ApplicationInstance *instance = desktop.allApplicationInstances[i];
if (instance->processID == pid) {
return instance->application;
}
}
return nullptr;
}
void ApplicationProcessTerminated(EsObjectID pid) {
for (uintptr_t i = 0; i < desktop.allApplicationInstances.Length(); i++) {
ApplicationInstance *instance = desktop.allApplicationInstances[i];
@ -1432,7 +1445,7 @@ void ApplicationInstanceCompleteSave(ApplicationInstance *fromInstance) {
// Configuration file management:
//////////////////////////////////////////////////////
void ConfigurationLoad() {
void ConfigurationLoadApplications() {
// Add applications provided by Desktop.
{
@ -1461,6 +1474,8 @@ void ConfigurationLoad() {
desktop.installedApplications.Add(application);
}
EsMutexAcquire(&api.systemConfigurationMutex);
for (uintptr_t i = 0; i < api.systemConfigurationGroups.Length(); i++) {
// Load information about installed applications.
@ -1492,6 +1507,7 @@ void ConfigurationLoad() {
READ_PERMISSION("permission_posix_subsystem", APPLICATION_PERMISSION_POSIX_SUBSYSTEM);
READ_PERMISSION("permission_run_temporary_application", APPLICATION_PERMISSION_RUN_TEMPORARY_APPLICATION);
READ_PERMISSION("permission_shutdown", APPLICATION_PERMISSION_SHUTDOWN);
READ_PERMISSION("permission_view_file_types", APPLICATION_PERMISSION_VIEW_FILE_TYPES);
desktop.installedApplications.Add(application);
@ -1500,34 +1516,33 @@ void ConfigurationLoad() {
}
}
EsMutexRelease(&api.systemConfigurationMutex);
EsSort(desktop.installedApplications.array, desktop.installedApplications.Length(),
sizeof(InstalledApplication *), [] (const void *_left, const void *_right, EsGeneric) {
InstalledApplication *left = *(InstalledApplication **) _left;
InstalledApplication *right = *(InstalledApplication **) _right;
return EsStringCompare(left->cName, EsCStringLength(left->cName), right->cName, EsCStringLength(right->cName));
}, 0);
}
// Set the system configuration for other applications to read.
// TODO Enforce a limit of 4MB on the size of the system configuration.
// TODO Alternatively, replace this with a growable EsBuffer.
const size_t bufferSize = 4194304;
char *buffer = (char *) EsHeapAllocate(bufferSize, false);
size_t position = 0;
void ConfigurationWriteSectionsToBuffer(const char *sectionClass, const char *section, EsBuffer *pipe) {
char buffer[4096];
EsMutexAcquire(&api.systemConfigurationMutex);
for (uintptr_t i = 0; i < api.systemConfigurationGroups.Length(); i++) {
EsSystemConfigurationGroup *group = &api.systemConfigurationGroups[i];
if (EsStringCompareRaw(group->sectionClass, group->sectionClassBytes, EsLiteral("font"))
&& EsStringCompareRaw(group->sectionClass, group->sectionClassBytes, EsLiteral("file_type"))
&& EsStringCompareRaw(group->section, group->sectionBytes, EsLiteral("ui"))) {
if ((sectionClass && EsStringCompareRaw(group->sectionClass, group->sectionClassBytes, sectionClass, -1))
|| (section && EsStringCompareRaw(group->section, group->sectionBytes, section, -1))) {
continue;
}
EsINIState s = {};
s.sectionClass = group->sectionClass, s.sectionClassBytes = group->sectionClassBytes;
s.section = group->section, s.sectionBytes = group->sectionBytes;
position += EsINIFormat(&s, buffer + position, bufferSize - position);
size_t bytes = EsINIFormat(&s, buffer, sizeof(buffer));
EsBufferWrite(pipe, buffer, bytes);
for (uintptr_t i = 0; i < group->itemCount; i++) {
EsSystemConfigurationItem *item = group->items + i;
@ -1538,12 +1553,12 @@ void ConfigurationLoad() {
s.key = item->key, s.keyBytes = item->keyBytes;
s.value = item->value, s.valueBytes = item->valueBytes;
position += EsINIFormat(&s, buffer + position, bufferSize - position);
size_t bytes = EsINIFormat(&s, buffer, sizeof(buffer));
EsBufferWrite(pipe, buffer, bytes);
}
}
EsSyscall(ES_SYSCALL_SYSTEM_CONFIGURATION_WRITE, (uintptr_t) buffer, position, 0, 0);
EsHeapFree(buffer);
EsMutexRelease(&api.systemConfigurationMutex);
}
//////////////////////////////////////////////////////
@ -1869,6 +1884,21 @@ void DesktopMessage2(EsMessage *message, uint8_t *buffer, EsBuffer *pipe) {
EsBufferWrite(pipe, &fileHandle, sizeof(fileHandle));
EsHandleClose(processHandle);
}
} else if (buffer[0] == DESKTOP_MSG_SYSTEM_CONFIGURATION_GET && pipe) {
ConfigurationWriteSectionsToBuffer("font", nullptr, pipe);
ConfigurationWriteSectionsToBuffer(nullptr, "ui", pipe);
} else if (buffer[0] == DESKTOP_MSG_REQUEST_SHUTDOWN) {
InstalledApplication *application = ApplicationFindByPID(message->desktop.processID);
if (application && (application->permissions & APPLICATION_PERMISSION_SHUTDOWN)) {
ShutdownModalCreate();
}
} else if (buffer[0] == DESKTOP_MSG_FILE_TYPES_GET && pipe) {
InstalledApplication *application = ApplicationFindByPID(message->desktop.processID);
if (application && (application->permissions & APPLICATION_PERMISSION_VIEW_FILE_TYPES)) {
ConfigurationWriteSectionsToBuffer("file_type", nullptr, pipe);
}
} else if (!instance) {
// -------------------------------------------------
// | Messages below here require a valid instance. |
@ -1924,10 +1954,6 @@ void DesktopMessage2(EsMessage *message, uint8_t *buffer, EsBuffer *pipe) {
desktop.installedApplications.Add(application);
ApplicationInstanceCreate(application->id, nullptr, nullptr);
}
} else if (buffer[0] == DESKTOP_MSG_REQUEST_SHUTDOWN) {
if (instance->application && (instance->application->permissions & APPLICATION_PERMISSION_SHUTDOWN)) {
ShutdownModalCreate();
}
}
}
@ -2062,7 +2088,7 @@ void DesktopMessage(EsMessage *message) {
}
void DesktopEntry() {
ConfigurationLoad();
ConfigurationLoadApplications();
EsMessage m = { MSG_SETUP_DESKTOP_UI };
EsMessagePost(nullptr, &m);

View File

@ -408,15 +408,14 @@ define ES_STRING_FORMAT_ENOUGH_SPACE ((_EsLongConstant) (-1))
define ES_STRING_FORMAT_SIMPLE (1 << 0)
define ES_PERMISSION_NETWORKING (1 << 0)
define ES_PERMISSION_PROCESS_CREATE (1 << 2)
define ES_PERMISSION_PROCESS_OPEN (1 << 3)
define ES_PERMISSION_SCREEN_MODIFY (1 << 4)
define ES_PERMISSION_SHUTDOWN (1 << 5)
define ES_PERMISSION_TAKE_SYSTEM_SNAPSHOT (1 << 6)
define ES_PERMISSION_SYSTEM_CONFIGURATION_WRITE (1 << 7)
define ES_PERMISSION_GET_VOLUME_INFORMATION (1 << 8)
define ES_PERMISSION_WINDOW_MANAGER (1 << 9)
define ES_PERMISSION_POSIX_SUBSYSTEM (1 << 10)
define ES_PERMISSION_PROCESS_CREATE (1 << 1)
define ES_PERMISSION_PROCESS_OPEN (1 << 2)
define ES_PERMISSION_SCREEN_MODIFY (1 << 3)
define ES_PERMISSION_SHUTDOWN (1 << 4)
define ES_PERMISSION_TAKE_SYSTEM_SNAPSHOT (1 << 5)
define ES_PERMISSION_GET_VOLUME_INFORMATION (1 << 6)
define ES_PERMISSION_WINDOW_MANAGER (1 << 7)
define ES_PERMISSION_POSIX_SUBSYSTEM (1 << 8)
define ES_PERMISSION_ALL ((_EsLongConstant) (-1))
define ES_PERMISSION_INHERIT ((_EsLongConstant) (1) << 63)
@ -844,8 +843,6 @@ enum EsSyscallType {
ES_SYSCALL_SYSTEM_GET_CONSTANTS
ES_SYSCALL_SYSTEM_TAKE_SNAPSHOT
ES_SYSCALL_SYSTEM_CONFIGURATION_WRITE
ES_SYSCALL_SYSTEM_CONFIGURATION_READ
// Misc.
@ -1868,7 +1865,7 @@ function void EsApplicationRunTemporary(ES_INSTANCE_TYPE *instance, STRING path)
function EsHandle EsTakeSystemSnapshot(int type, size_t *bufferSize);
function EsInstance *_EsInstanceCreate(size_t bytes, EsMessage *message, STRING name = BLANK_STRING);
function EsError EsHandleClose(EsHandle handle);
function void EsSystemShowShutdownDialog(ES_INSTANCE_TYPE *instance);
function void EsSystemShowShutdownDialog();
function void EsPOSIXInitialise(int *argc, char ***argv);
function intptr_t EsPOSIXSystemCall(intptr_t n, intptr_t a1, intptr_t a2, intptr_t a3, intptr_t a4, intptr_t a5, intptr_t a6);
@ -1881,11 +1878,9 @@ function uintptr_t _EsSyscall(uintptr_t a, uintptr_t b, uintptr_t c, uintptr_t d
function uint64_t EsSystemGetConstant(uintptr_t index);
function EsSystemConfigurationGroup *EsSystemConfigurationReadAll(size_t *groupCount); // Read with the message mutex acquired.
function int64_t EsSystemConfigurationReadInteger(STRING section, STRING key, int64_t defaultValue = 0);
function int64_t EsSystemConfigurationGroupReadInteger(EsSystemConfigurationGroup *group, STRING key, int64_t defaultValue = 0);
function char *EsSystemConfigurationReadString(STRING section, STRING key, size_t *valueBytes = ES_NULL); // Free with EsHeapFree.
function char *EsSystemConfigurationGroupReadString(EsSystemConfigurationGroup *group, STRING key, size_t *valueBytes = ES_NULL); // Free with EsHeapFree.
function void EsSystemConfigurationReadFileTypes(EsBuffer *buffer); // Read the "file_type" sections of the system configuration INI to the buffer.
// INI files.
@ -2030,7 +2025,7 @@ function void EsDrawBitmap(EsPainter *painter, EsRectangle region, uint32_t *bit
function void EsDrawBitmapScaled(EsPainter *painter, EsRectangle destinationRegion, EsRectangle sourceRegion, uint32_t *bits, uintptr_t stride, uint16_t alpha); // Set alpha to 0xFFFF if source is opaque.
function void EsDrawBlock(EsPainter *painter, EsRectangle bounds, uint32_t mainColor);
function void EsDrawClear(EsPainter *painter, EsRectangle bounds);
function void EsDrawContent(EsPainter *painter, EsElement *element, EsRectangle rectangle, STRING text, uint32_t iconID = 0, uint32_t flags = ES_FLAGS_DEFAULT, EsTextSelection *selectionProperties = nullptr);
function void EsDrawContent(EsPainter *painter, EsElement *element, EsRectangle rectangle, STRING text, uint32_t iconID = 0, uint32_t flags = ES_FLAGS_DEFAULT, EsTextSelection *selectionProperties = ES_NULL);
function void EsDrawInvert(EsPainter *painter, EsRectangle bounds);
function void EsDrawLine(EsPainter *painter, float *vertices, size_t vertexCount, uint32_t color, float width, uint32_t flags); // Vertices are pairs of x,y coordinates.
function void EsDrawRectangle(EsPainter *painter, EsRectangle bounds, uint32_t mainColor, uint32_t borderColor, EsRectangle borderSize);
@ -2252,7 +2247,7 @@ function void EsElementSetDisabled(EsElement *element, bool disabled = true);
function void EsElementSetHidden(EsElement *element, bool hidden = true);
function void EsElementSetCallback(EsElement *element, EsUICallbackFunction callback);
function void EsElementGetSize(EsElement *element, int *width, int *height);
function void EsElementRepaint(EsElement *element, const EsRectangle *region = nullptr); // Mark an element to be repainted. If region is null, then the whole element is repainted.
function void EsElementRepaint(EsElement *element, const EsRectangle *region = ES_NULL); // Mark an element to be repainted. If region is null, then the whole element is repainted.
function void EsElementRepaintForScroll(EsElement *element, EsMessage *message); // Minimal repaint for ES_MSG_SCROLL_X/Y.
function void EsElementRelayout(EsElement *element);
function void EsElementSetCellRange(EsElement *element, int xFrom, int yFrom, int xTo = -1, int yTo = -1); // Use only if the parent is a ES_PANEL_TABLE.

View File

@ -457,6 +457,8 @@ void FontInitialise() {
FontDatabaseEntry nullFont = {};
fontManagement.database.Add(nullFont);
EsMutexAcquire(&api.systemConfigurationMutex);
for (uintptr_t i = 0; i < api.systemConfigurationGroups.Length(); i++) {
EsSystemConfigurationGroup *g = &api.systemConfigurationGroups[i];
@ -511,6 +513,8 @@ void FontInitialise() {
fontManagement.database.Add(entry);
}
}
EsMutexRelease(&api.systemConfigurationMutex);
}
EsFontFamily FontGetStandardFamily(EsFontFamily family) {

View File

@ -1586,6 +1586,7 @@ SYSCALL_IMPLEMENT(ES_SYSCALL_PIPE_CREATE) {
}
SYSCALL_IMPLEMENT(ES_SYSCALL_PIPE_READ) {
if (!argument2) SYSCALL_RETURN(ES_SUCCESS, false);
Pipe *pipe;
SYSCALL_HANDLE(argument0, KERNEL_OBJECT_PIPE, pipe, 1);
SYSCALL_BUFFER(argument1, argument2, 2, false);
@ -1593,59 +1594,13 @@ SYSCALL_IMPLEMENT(ES_SYSCALL_PIPE_READ) {
}
SYSCALL_IMPLEMENT(ES_SYSCALL_PIPE_WRITE) {
if (!argument2) SYSCALL_RETURN(ES_SUCCESS, false);
Pipe *pipe;
SYSCALL_HANDLE(argument0, KERNEL_OBJECT_PIPE, pipe, 1);
SYSCALL_BUFFER(argument1, argument2, 2, true /* write */);
SYSCALL_RETURN(pipe->Access((void *) argument1, argument2, true, true), false);
}
KMutex systemConfigurationMutex;
ConstantBuffer *systemConfiguration;
SYSCALL_IMPLEMENT(ES_SYSCALL_SYSTEM_CONFIGURATION_WRITE) {
SYSCALL_PERMISSION(ES_PERMISSION_SYSTEM_CONFIGURATION_WRITE);
// TODO Broadcast message?
if (argument1 > SYSCALL_BUFFER_LIMIT) {
SYSCALL_RETURN(ES_FATAL_ERROR_INVALID_BUFFER, true);
}
ConstantBuffer *buffer = (ConstantBuffer *) EsHeapAllocate(sizeof(ConstantBuffer) + argument1, false, K_PAGED);
if (!buffer) SYSCALL_RETURN(ES_ERROR_INSUFFICIENT_RESOURCES, false);
EsMemoryZero(buffer, sizeof(ConstantBuffer));
buffer->handles = 1;
buffer->bytes = argument1;
buffer->isPaged = true;
EsDefer(CloseHandleToObject(buffer, KERNEL_OBJECT_CONSTANT_BUFFER));
SYSCALL_READ(buffer + 1, argument0, argument1);
KMutexAcquire(&systemConfigurationMutex);
if (systemConfiguration) CloseHandleToObject(systemConfiguration, KERNEL_OBJECT_CONSTANT_BUFFER);
OpenHandleToObject(buffer, KERNEL_OBJECT_CONSTANT_BUFFER);
systemConfiguration = buffer;
KMutexRelease(&systemConfigurationMutex);
SYSCALL_RETURN(ES_SUCCESS, false);
}
SYSCALL_IMPLEMENT(ES_SYSCALL_SYSTEM_CONFIGURATION_READ) {
EsHandle handle = ES_INVALID_HANDLE;
size_t bytes = 0;
KMutexAcquire(&systemConfigurationMutex);
if (systemConfiguration && OpenHandleToObject(systemConfiguration, KERNEL_OBJECT_CONSTANT_BUFFER)) {
bytes = systemConfiguration->bytes;
handle = currentProcess->handleTable.OpenHandle(systemConfiguration, 0, KERNEL_OBJECT_CONSTANT_BUFFER);
}
KMutexRelease(&systemConfigurationMutex);
SYSCALL_WRITE(argument2, &bytes, sizeof(bytes));
SYSCALL_RETURN(handle, false);
}
SYSCALL_IMPLEMENT(ES_SYSCALL_EVENT_SINK_CREATE) {
EventSink *sink = (EventSink *) EsHeapAllocate(sizeof(EventSink), true, K_FIXED);

View File

@ -162,7 +162,7 @@ EsStringFormatV=160
EsStringFormatAppend=161
EsStringFormatAppendV=162
EsStringLength=163
EsSystemConfigurationReadAll=164
EsSystemConfigurationReadFileTypes=164
EsImageLoad=165
EsStringStartsWith=166
EsStringZeroTerminate=167
@ -294,9 +294,7 @@ EsTextPlanGetLineCount=292
EsTextPlanDestroy=293
EsTextDisplaySetContents=294
EsSystemConfigurationReadInteger=295
EsSystemConfigurationGroupReadInteger=296
EsSystemConfigurationReadString=297
EsSystemConfigurationGroupReadString=298
EsGameControllerStatePoll=299
EsInstanceDestroy=300
EsRandomU8=301

View File

@ -497,6 +497,7 @@ typedef struct FileType {
const char *name;
const char *icon;
int id, openID;
bool hasThumbnailGenerator;
} FileType;
typedef struct Handler {
@ -719,6 +720,7 @@ void ParseApplicationManifest(const char *manifestPath) {
INI_READ_STRING_PTR(extension, fileType->extension);
INI_READ_STRING_PTR(name, fileType->name);
INI_READ_STRING_PTR(icon, fileType->icon);
INI_READ_BOOL(has_thumbnail_generator, fileType->hasThumbnailGenerator);
} else if (0 == strcmp(s.section, "embed") && s.key[0] != ';' && s.value[0]) {
BundleInput input = { 0 };
input.path = s.value;
@ -821,6 +823,7 @@ void OutputSystemConfiguration() {
FilePrintFormat(file, "name=%s\n", applications[i].fileTypes[j].name);
FilePrintFormat(file, "icon=%s\n", applications[i].fileTypes[j].icon);
FilePrintFormat(file, "open=%d\n", applications[i].fileTypes[j].openID);
FilePrintFormat(file, "has_thumbnail_generator=%d\n", applications[i].fileTypes[j].hasThumbnailGenerator);
}
for (uintptr_t j = 0; j < arrlenu(applications[i].handlers); j++) {