update x11 backend for desktop request changes

This commit is contained in:
nakst 2022-01-07 09:14:10 +00:00
parent 9e610bd928
commit 9c4c48505d
1 changed files with 68 additions and 46 deletions

View File

@ -102,9 +102,7 @@ pthread_mutex_t memoryMappingsMutex;
Array<MemoryMapping> memoryMappings; Array<MemoryMapping> memoryMappings;
pthread_mutex_t windowsMutex; pthread_mutex_t windowsMutex;
Array<UIWindow *> windows; Array<UIWindow *> windows;
pthread_mutex_t desktopRequestsMutex; int desktopRequestPipe, desktopResponsePipe;
Array<DesktopRequest> desktopRequests;
sem_t desktopRequestsAvailable;
volatile EsObjectID objectIDAllocator = 1; volatile EsObjectID objectIDAllocator = 1;
extern BundleHeader _binary_bin_bundle_dat_start; extern BundleHeader _binary_bin_bundle_dat_start;
@ -345,26 +343,15 @@ uintptr_t _APISyscall(uintptr_t index, uintptr_t argument0, uintptr_t argument1,
*(EsHandle *) argument0 = HandleOpen(readEnd); *(EsHandle *) argument0 = HandleOpen(readEnd);
*(EsHandle *) argument1 = HandleOpen(writeEnd); *(EsHandle *) argument1 = HandleOpen(writeEnd);
return ES_SUCCESS;
} else if (index == ES_SYSCALL_MESSAGE_DESKTOP) {
const uint8_t *message = (const uint8_t *) argument0;
size_t messageBytes = argument1;
DesktopRequest request = {};
request.message = (uint8_t *) EsHeapAllocate(messageBytes, false);
if (!request.message) return ES_ERROR_INSUFFICIENT_RESOURCES;
EsMemoryCopy(request.message, message, messageBytes);
request.bytes = messageBytes;
request.window = argument2;
request.pipe = argument3 ? dup(((Node *) HandleResolve(argument3, OBJECT_NODE))->fd) : -1;
pthread_mutex_lock(&desktopRequestsMutex);
desktopRequests.Add(request);
sem_post(&desktopRequestsAvailable);
pthread_mutex_unlock(&desktopRequestsMutex);
return ES_SUCCESS; return ES_SUCCESS;
} else if (index == ES_SYSCALL_PIPE_READ) { } else if (index == ES_SYSCALL_PIPE_READ) {
Node *node = (Node *) HandleResolve(argument0, OBJECT_NODE); Node *node = (Node *) HandleResolve(argument0, OBJECT_NODE);
ssize_t x = read(node->fd, (void *) argument1, argument2); ssize_t x = read(node->fd, (void *) argument1, argument2);
return x < 0 ? ES_ERROR_UNKNOWN : x; return x < 0 ? ES_ERROR_UNKNOWN : x;
} else if (index == ES_SYSCALL_PIPE_WRITE) {
Node *node = (Node *) HandleResolve(argument0, OBJECT_NODE);
ssize_t x = write(node->fd, (void *) argument1, argument2);
return x < 0 ? ES_ERROR_UNKNOWN : x;
} else if (index == ES_SYSCALL_PRINT) { } else if (index == ES_SYSCALL_PRINT) {
fwrite((void *) argument0, 1, argument1, stderr); fwrite((void *) argument0, 1, argument1, stderr);
return ES_SUCCESS; return ES_SUCCESS;
@ -704,46 +691,61 @@ void *UIThread(void *) {
void *DesktopThread(void *) { void *DesktopThread(void *) {
while (true) { while (true) {
sem_wait(&desktopRequestsAvailable); uint32_t length;
pthread_mutex_lock(&desktopRequestsMutex); EsObjectID embeddedWindowID;
assert(desktopRequests.Length()); if (sizeof(length) != read(desktopRequestPipe, &length, sizeof(length))) break;
DesktopRequest request = desktopRequests.First(); if (sizeof(embeddedWindowID) != read(desktopRequestPipe, &embeddedWindowID, sizeof(embeddedWindowID))) break;
desktopRequests.Delete(0); uint8_t *message = (uint8_t *) malloc(length);
pthread_mutex_unlock(&desktopRequestsMutex); if (length != read(desktopRequestPipe, message, length)) break;
uint32_t responseLength = 0;
uint8_t *message = request.message;
size_t messageBytes = request.bytes;
EsHandle windowHandle = request.window;
int pipe = request.pipe;
if (message[0] == DESKTOP_MSG_SYSTEM_CONFIGURATION_GET) { if (message[0] == DESKTOP_MSG_SYSTEM_CONFIGURATION_GET) {
// TODO List fonts. // TODO List all fonts.
write(pipe, systemConfiguration, EsCRTstrlen(systemConfiguration)); responseLength = EsCRTstrlen(systemConfiguration);
assert(pipe != -1); write(desktopResponsePipe, &responseLength, sizeof(responseLength));
write(desktopResponsePipe, systemConfiguration, responseLength);
} else if (message[0] == DESKTOP_MSG_SET_TITLE) { } else if (message[0] == DESKTOP_MSG_SET_TITLE) {
UIWindow *window = (UIWindow *) HandleResolve(windowHandle, OBJECT_WINDOW);
pthread_mutex_lock(&windowsMutex); pthread_mutex_lock(&windowsMutex);
char cTitle[256];
snprintf(cTitle, sizeof(cTitle), "%.*s", (int) messageBytes - 1, message + 1); UIWindow *window = nullptr;
XStoreName(ui.display, window->window, cTitle);
for (uintptr_t i = 0; i < windows.Length(); i++) {
if (windows[i]->id == embeddedWindowID) {
window = windows[i];
break;
}
}
if (window) {
char cTitle[256];
snprintf(cTitle, sizeof(cTitle), "%.*s", (int) length - 1, message + 1);
XStoreName(ui.display, window->window, cTitle);
}
pthread_mutex_unlock(&windowsMutex); pthread_mutex_unlock(&windowsMutex);
write(desktopResponsePipe, &responseLength, sizeof(responseLength));
} else if (message[0] == DESKTOP_MSG_SET_ICON) { } else if (message[0] == DESKTOP_MSG_SET_ICON) {
// TODO. // TODO.
write(desktopResponsePipe, &responseLength, sizeof(responseLength));
} else if (message[0] == DESKTOP_MSG_SET_MODIFIED) { } else if (message[0] == DESKTOP_MSG_SET_MODIFIED) {
// TODO. // TODO.
write(desktopResponsePipe, &responseLength, sizeof(responseLength));
} else if (message[0] == DESKTOP_MSG_CLIPBOARD_GET) { } else if (message[0] == DESKTOP_MSG_CLIPBOARD_GET) {
ClipboardInformation clipboardInformation = {}; ClipboardInformation clipboardInformation = {};
EsHandle fileHandle = ES_INVALID_HANDLE; EsHandle fileHandle = ES_INVALID_HANDLE;
write(pipe, &clipboardInformation, sizeof(clipboardInformation)); responseLength = sizeof(clipboardInformation) + sizeof(fileHandle);
write(pipe, &fileHandle, sizeof(fileHandle)); write(desktopResponsePipe, &responseLength, sizeof(responseLength));
write(desktopResponsePipe, &clipboardInformation, sizeof(clipboardInformation));
write(desktopResponsePipe, &fileHandle, sizeof(fileHandle));
} else { } else {
fprintf(stderr, "Unimplemented desktop message %d.\n", message[0]); fprintf(stderr, "Unimplemented desktop message %d.\n", message[0]);
exit(1); exit(1);
} }
EsHeapFree(message); free(message);
if (pipe != -1) close(pipe);
} }
return nullptr;
} }
int main() { int main() {
@ -751,12 +753,15 @@ int main() {
pthread_mutex_init(&handlesMutex, nullptr); pthread_mutex_init(&handlesMutex, nullptr);
pthread_mutex_init(&messageQueueMutex, nullptr); pthread_mutex_init(&messageQueueMutex, nullptr);
pthread_mutex_init(&windowsMutex, nullptr); pthread_mutex_init(&windowsMutex, nullptr);
pthread_mutex_init(&desktopRequestsMutex, nullptr);
sem_init(&desktopRequestsAvailable, 0, 0);
sem_init(&messagesAvailable, 0, 0); sem_init(&messagesAvailable, 0, 0);
XInitThreads(); XInitThreads();
for (uintptr_t i = 0; i < 0x20; i++) {
// Prevent the first few handles from being used.
HandleOpen(nullptr);
}
ui.display = XOpenDisplay(NULL); ui.display = XOpenDisplay(NULL);
ui.visual = XDefaultVisual(ui.display, 0); ui.visual = XDefaultVisual(ui.display, 0);
ui.windowClosedID = XInternAtom(ui.display, "WM_DELETE_WINDOW", 0); ui.windowClosedID = XInternAtom(ui.display, "WM_DELETE_WINDOW", 0);
@ -770,10 +775,6 @@ int main() {
ui.xim = XOpenIM(ui.display, 0, 0, 0); ui.xim = XOpenIM(ui.display, 0, 0, 0);
} }
pthread_t uiThread, desktopThread;
pthread_create(&uiThread, nullptr, UIThread, nullptr);
pthread_create(&desktopThread, nullptr, DesktopThread, nullptr);
globalData.clickChainTimeoutMs = 300; globalData.clickChainTimeoutMs = 300;
globalData.uiScale = 1.0f; globalData.uiScale = 1.0f;
globalData.useSmartQuotes = true; globalData.useSmartQuotes = true;
@ -805,6 +806,27 @@ int main() {
EsCRTstrcpy(initialMountPoint->prefix, "0:"); EsCRTstrcpy(initialMountPoint->prefix, "0:");
// TODO Settings mount point. // TODO Settings mount point.
int pipes[2];
Node *pipeObject;
pipe(pipes);
desktopRequestPipe = pipes[0];
pipeObject = (Node *) EsHeapAllocate(sizeof(Node), true);
pipeObject->type = OBJECT_NODE;
pipeObject->referenceCount = 1;
pipeObject->fd = pipes[1];
startupHeader->desktopRequestPipe = HandleOpen(pipeObject);
pipe(pipes);
desktopResponsePipe = pipes[1];
pipeObject = (Node *) EsHeapAllocate(sizeof(Node), true);
pipeObject->type = OBJECT_NODE;
pipeObject->referenceCount = 1;
pipeObject->fd = pipes[0];
startupHeader->desktopResponsePipe = HandleOpen(pipeObject);
pthread_t uiThread, desktopThread;
pthread_create(&uiThread, nullptr, UIThread, nullptr);
pthread_create(&desktopThread, nullptr, DesktopThread, nullptr);
bundleDesktop.base = &_binary_bin_bundle_dat_start; bundleDesktop.base = &_binary_bin_bundle_dat_start;
EsProcessStartupInformation startupInformation = {}; EsProcessStartupInformation startupInformation = {};