more x11 backend work

This commit is contained in:
nakst 2022-01-15 18:07:31 +00:00
parent b6f715eedc
commit f224b596f0
4 changed files with 100 additions and 39 deletions

View File

@ -4,25 +4,16 @@
// TODO Tabs:
// - New tab page - search; recent files.
// - Right click menu.
// - Duplicate tabs.
// TODO Graphical issues:
// - Inactivate windows don't dim outline around tabs.
// - Duplicating tabs.
// TODO Task bar:
// - Right click menu.
// - Notification area?
// TODO Desktop experience:
// - Alt+tab.
// - Changing wallpaper.
// TODO Global shortcuts:
// - Restoring closed tabs.
// - Switch to window.
// - Print screen.
// TODO On inactivate windows dim outline around tabs.
// TODO Alt+tab.
// TODO Restarting Desktop if it crashes.
// TODO Make sure applications can't delete |Fonts:.
// TODO Handle open document deletion.
@ -1886,6 +1877,10 @@ bool ApplicationInstanceStart(int64_t applicationID, _EsApplicationStartupInform
}
if (application->permissions & APPLICATION_PERMISSION_ALL_FILES) {
// We will inform the process of new and removed mount points on the message thread,
// in response to ES_MSG_REGISTER_FILE_SYSTEM and ES_MSG_UNREGISTER_FILE_SYSTEM.
EsMessageMutexCheck();
for (uintptr_t i = 0; i < api.mountPoints.Length(); i++) {
initialMountPoints.Add(api.mountPoints[i]);
handleDuplicateList.Add(api.mountPoints[i].base);

View File

@ -4251,13 +4251,14 @@ UIFont *UIFontCreate(const char *cPath, uint32_t size) {
#ifdef UI_FREETYPE
if (cPath) {
FT_New_Face(ui.ft, cPath, 0, &font->font);
FT_Set_Char_Size(font->font, 0, size * 64, 100, 100);
FT_Load_Char(font->font, 'a', FT_LOAD_DEFAULT);
font->glyphWidth = font->font->glyph->advance.x / 64;
font->glyphHeight = (font->font->size->metrics.ascender - font->font->size->metrics.descender) / 64;
font->isFreeType = true;
return font;
if (!FT_New_Face(ui.ft, cPath, 0, &font->font)) {
FT_Set_Char_Size(font->font, 0, size * 64, 100, 100);
FT_Load_Char(font->font, 'a', FT_LOAD_DEFAULT);
font->glyphWidth = font->font->glyph->advance.x / 64;
font->glyphHeight = (font->font->size->metrics.ascender - font->font->size->metrics.descender) / 64;
font->isFreeType = true;
return font;
}
}
#endif

View File

@ -4,4 +4,4 @@ mkdir -p bin/include_x11
cp root/Applications/POSIX/include/essence.h bin/include_x11
cp root/Essence/Desktop.esx bin/bundle.dat
ld -r -b binary -o bin/Object\ Files/bundle.o bin/bundle.dat
g++ -o bin/hello_x11 util/x11/platform.cpp $1 bin/Object\ Files/bundle.o -lfreetype -lharfbuzz -lX11 -pthread -g -fno-exceptions -Ibin/include_x11 -I. -I/usr/include/freetype2 -DNO_API_TABLE -DUSE_PLATFORM_HEAP -DUSE_FREETYPE_AND_HARFBUZZ -DUSE_STB_SPRINTF -D_start=_StartApplication -D_init=EsHeapValidate -DES_FORWARD -DARRAY_DEFINITIONS_ONLY -Wall -Wextra -Wno-empty-body -Wno-deprecated-declarations -Wno-unknown-pragmas -Wno-missing-field-initializers -Wno-unused-parameter -Wno-unused-variable -Wno-unused-function -fsanitize=address
g++ -o bin/hello_x11 util/x11/platform.cpp $1 bin/Object\ Files/bundle.o -lfreetype -lharfbuzz -lX11 -pthread -g -fno-exceptions -Ibin/include_x11 -I. -I/usr/include/freetype2 -DNO_API_TABLE -DUSE_PLATFORM_HEAP -DUSE_FREETYPE_AND_HARFBUZZ -DUSE_STB_SPRINTF -D_start=_StartApplication -D_init=EsHeapValidate -DINSTALLATION_NAME=HelloX11 -DES_FORWARD -DARRAY_DEFINITIONS_ONLY -Wall -Wextra -Wno-empty-body -Wno-deprecated-declarations -Wno-unknown-pragmas -Wno-missing-field-initializers -Wno-unused-parameter -Wno-unused-variable -Wno-unused-function -O2

View File

@ -19,11 +19,15 @@
#include <errno.h>
#include <sys/statvfs.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xatom.h>
#include <X11/cursorfont.h>
#define _STRINGIFY(x) #x
#define STRINGIFY(x) _STRINGIFY(x)
extern "C" void _StartApplication();
struct Object {
@ -75,8 +79,8 @@ struct UIWindow : Object {
XImage *image;
XIC xic;
void *apiObject;
int x, y;
int width, height;
int32_t x, y;
int32_t width, height;
uint32_t *bits;
};
@ -115,6 +119,7 @@ pthread_mutex_t memoryMappingsMutex;
Array<MemoryMapping> memoryMappings;
pthread_mutex_t windowsMutex;
Array<UIWindow *> windows;
UIWindow *mainWindow;
int desktopRequestPipe, desktopResponsePipe;
volatile EsObjectID objectIDAllocator = 1;
extern BundleHeader _binary_bin_bundle_dat_start;
@ -292,6 +297,7 @@ void ReferenceClose(Object *object) {
EsHeapFree(((SharedMemoryRegion *) object)->pointer);
} else if (object->type == OBJECT_NODE) {
close(((Node *) object)->fd);
} else if (object->type == OBJECT_WINDOW) {
} else {
assert(false); // TODO.
}
@ -601,7 +607,7 @@ uintptr_t _APISyscall(uintptr_t index, uintptr_t argument0, uintptr_t argument1,
UIWindow *window = (UIWindow *) EsHeapAllocate(sizeof(UIWindow), true);
window->type = OBJECT_WINDOW;
window->referenceCount = 1;
window->referenceCount = 2;
window->id = __sync_fetch_and_add(&objectIDAllocator, 1);
window->apiObject = apiObject;
@ -716,14 +722,37 @@ uintptr_t _APISyscall(uintptr_t index, uintptr_t argument0, uintptr_t argument1,
EventReset(event);
return ES_SUCCESS;
} else if (index == ES_SYSCALL_WAIT) {
assert(argument1 == 1); // TODO Waiting on multiple object.
assert(argument1 == 1); // TODO Waiting on multiple objects.
Object *object = HandleResolve(*(EsHandle *) argument0, 0);
assert(object->type == OBJECT_EVENT); // TODO Waiting on other object types.
Event *event = (Event *) object;
return EventWait(event, argument2) ? ES_ERROR_TIMEOUT_REACHED : 0;
} else if (index == ES_SYSCALL_PROCESS_TERMINATE) {
exit(argument1);
} else if (index == ES_SYSCALL_PROCESS_CRASH) {
assert(false); // Do an assertion failure so it can be caught by an attached debugger.
} else if (index == ES_SYSCALL_YIELD_SCHEDULER) {
return ES_SUCCESS;
} else if (index == ES_SYSCALL_NODE_OPEN) {
return ES_ERROR_FILE_DOES_NOT_EXIST; // TODO File and directory operations.
} else if (index == ES_SYSCALL_WINDOW_CLOSE) {
UIWindow *window = (UIWindow *) HandleResolve(argument0, OBJECT_WINDOW);
pthread_mutex_lock(&windowsMutex);
EsHeapFree(window->bits);
window->image->data = NULL;
XDestroyImage(window->image);
XDestroyIC(window->xic);
XDestroyWindow(ui.display, window->window);
windows.FindAndDelete(window, true);
if (mainWindow == window) {
_EsMessageWithObject m = { .message = { .type = ES_MSG_APPLICATION_EXIT } };
MessagePost(&m);
}
pthread_mutex_unlock(&windowsMutex);
ReferenceClose(window);
return ES_SUCCESS;
} else {
fprintf(stderr, "Unimplemented system call '%s' (%ld).\n", EnumLookupNameFromValue(enumStrings_EsSyscallType, index), index);
@ -796,8 +825,8 @@ void UIProcessEvent(XEvent *event) {
}
if (event->type == ClientMessage && (Atom) event->xclient.data.l[0] == ui.windowClosedID) {
// TODO Properly exiting.
exit(0);
_EsMessageWithObject m = { .message = { .type = ES_MSG_TAB_CLOSE_REQUEST, .tabOperation = { .id = mainWindow->id } } };
MessagePost(&m);
} else if (event->type == ConfigureNotify) {
UIWindow *window = UIFindWindow(event->xconfigure.window);
@ -805,14 +834,25 @@ void UIProcessEvent(XEvent *event) {
window->y = event->xconfigure.y;
if (window->width != event->xconfigure.width || window->height != event->xconfigure.height) {
int32_t oldWidth = window->width, oldHeight = window->height;
uint32_t *oldBits = window->bits;
window->width = event->xconfigure.width;
window->height = event->xconfigure.height;
window->bits = (uint32_t *) EsHeapReallocate(window->bits, window->width * window->height * 4, false); // TODO Copying old bits correctly.
window->bits = (uint32_t *) EsHeapAllocate(window->width * window->height * 4, false);
window->image->width = window->width;
window->image->height = window->height;
window->image->bytes_per_line = window->width * 4;
window->image->data = (char *) window->bits;
for (int32_t y = 0; y < window->height; y++) {
for (int32_t x = 0; x < window->width; x++) {
window->bits[y * window->width + x] = y < oldHeight && x < oldWidth ? oldBits[y * oldWidth + x] : 0xFFFFFFFF;
}
}
EsHeapFree(oldBits, oldWidth * oldHeight * 4);
if (window->apiObject) {
_EsMessageWithObject m = {};
m.object = window->apiObject;
@ -872,8 +912,9 @@ void UIProcessEvent(XEvent *event) {
void *UIThread(void *) {
UIWindow *window = (UIWindow *) EsHeapAllocate(sizeof(UIWindow), true);
mainWindow = window;
window->type = OBJECT_WINDOW;
window->referenceCount = 1;
window->referenceCount = 2;
window->id = __sync_fetch_and_add(&objectIDAllocator, 1);
XSetWindowAttributes attributes = {};
window->window = XCreateWindow(ui.display, DefaultRootWindow(ui.display), 0, 0, 800, 600, 0, 0,
@ -891,6 +932,7 @@ void *UIThread(void *) {
_EsMessageWithObject m = {};
m.message.type = ES_MSG_INSTANCE_CREATE;
m.message.createInstance.window = HandleOpen(window);
// TODO _EsApplicationStartupInformation.
MessagePost(&m);
while (true) {
@ -986,6 +1028,22 @@ void *DesktopThread(void *) {
}
int main() {
char *xdgConfigHome = getenv("XDG_CONFIG_HOME");
char *userHome = getenv("HOME");
if (!xdgConfigHome) {
const char *defaultConfig = "/.config";
xdgConfigHome = (char *) malloc(strlen(userHome) + strlen(defaultConfig) + 1);
strcpy(xdgConfigHome, userHome);
strcat(xdgConfigHome, defaultConfig);
}
char *applicationConfigDirectory = (char *) malloc(strlen(xdgConfigHome) + 1 + strlen(STRINGIFY(INSTALLATION_NAME)) + 1);
strcpy(applicationConfigDirectory, xdgConfigHome);
strcat(applicationConfigDirectory, "/");
strcat(applicationConfigDirectory, STRINGIFY(INSTALLATION_NAME));
mkdir(applicationConfigDirectory, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
pthread_mutex_init(&memoryMappingsMutex, nullptr);
pthread_mutex_init(&handlesMutex, nullptr);
pthread_mutex_init(&messageQueueMutex, nullptr);
@ -1025,23 +1083,30 @@ int main() {
globalDataRegion->pointer = &globalData;
globalDataRegion->bytes = sizeof(globalData);
Node *baseMountPoint = (Node *) EsHeapAllocate(sizeof(Node), true);
baseMountPoint->type = OBJECT_NODE;
baseMountPoint->referenceCount = 1;
baseMountPoint->fd = open("/", O_DIRECTORY | O_PATH);
Node *rootMountPoint = (Node *) EsHeapAllocate(sizeof(Node), true);
rootMountPoint->type = OBJECT_NODE;
rootMountPoint->referenceCount = 1;
rootMountPoint->fd = open("/", O_DIRECTORY | O_PATH);
Node *settingsMountPoint = (Node *) EsHeapAllocate(sizeof(Node), true);
settingsMountPoint->type = OBJECT_NODE;
settingsMountPoint->referenceCount = 1;
settingsMountPoint->fd = open(applicationConfigDirectory, O_DIRECTORY | O_PATH);
SharedMemoryRegion *startupData = (SharedMemoryRegion *) EsHeapAllocate(sizeof(SharedMemoryRegion), true);
startupData->type = OBJECT_SHMEM;
startupData->referenceCount = 1;
startupData->bytes = sizeof(SystemStartupDataHeader) + sizeof(EsMountPoint);
startupData->bytes = sizeof(SystemStartupDataHeader) + sizeof(EsMountPoint) * 2;
startupData->pointer = EsHeapAllocate(startupData->bytes, true);
SystemStartupDataHeader *startupHeader = (SystemStartupDataHeader *) startupData->pointer;
startupHeader->initialMountPointCount = 1;
EsMountPoint *initialMountPoint = (EsMountPoint *) (startupHeader + 1);
initialMountPoint->prefixBytes = 2;
initialMountPoint->base = HandleOpen(baseMountPoint);
EsCRTstrcpy(initialMountPoint->prefix, "0:");
// TODO Settings mount point.
startupHeader->initialMountPointCount = 2;
EsMountPoint *mountPoint0 = (EsMountPoint *) (startupHeader + 1);
mountPoint0->prefixBytes = 2;
mountPoint0->base = HandleOpen(rootMountPoint);
EsCRTstrcpy(mountPoint0->prefix, "0:");
EsMountPoint *mountPoint1 = (EsMountPoint *) (mountPoint0 + 1);
mountPoint1->prefixBytes = 9;
mountPoint1->base = HandleOpen(settingsMountPoint);
EsCRTstrcpy(mountPoint1->prefix, "|Settings:");
int pipes[2];
Node *pipeObject;