diff options
author | Andreas Kling <awesomekling@gmail.com> | 2019-02-17 00:13:47 +0100 |
---|---|---|
committer | Andreas Kling <awesomekling@gmail.com> | 2019-02-17 00:13:47 +0100 |
commit | 640360e958d6dea05ba0e294af52160bc10725cb (patch) | |
tree | 509ac7609062108169b8332064ebfae40edef1c6 | |
parent | 0b1b21d62286b73b8c59a2ce12e75a6de0f84f13 (diff) | |
download | serenity-640360e958d6dea05ba0e294af52160bc10725cb.zip |
Move WindowServer to userspace.
This is a monster patch that required changing a whole bunch of things.
There are performance and stability issues all over the place, but it works.
Pretty cool, I have to admit :^)
41 files changed, 325 insertions, 463 deletions
diff --git a/Kernel/BochsVGADevice.cpp b/Kernel/BochsVGADevice.cpp index a91ca25709..0ce9c60a01 100644 --- a/Kernel/BochsVGADevice.cpp +++ b/Kernel/BochsVGADevice.cpp @@ -95,9 +95,9 @@ Region* BochsVGADevice::mmap(Process& process, LinearAddress preferred_laddr, si 0, "BochsVGA Framebuffer", true, true); - kprintf("BochsVGA: %s(%u) created Region{%p} for framebuffer P%x\n", + kprintf("BochsVGA: %s(%u) created Region{%p} with size %u for framebuffer P%x with laddr L%x\n", process.name().characters(), process.pid(), - region, framebuffer_address().as_ptr()); + region, region->size(), framebuffer_address().as_ptr(), region->laddr().get()); ASSERT(region); return region; } diff --git a/Kernel/FileDescriptor.cpp b/Kernel/FileDescriptor.cpp index 5c171879eb..0f4dcde420 100644 --- a/Kernel/FileDescriptor.cpp +++ b/Kernel/FileDescriptor.cpp @@ -10,6 +10,7 @@ #include <Kernel/Socket.h> #include <Kernel/Process.h> #include <Kernel/BlockDevice.h> +#include <Kernel/MemoryManager.h> RetainPtr<FileDescriptor> FileDescriptor::create(RetainPtr<Inode>&& inode) { @@ -54,6 +55,10 @@ FileDescriptor::FileDescriptor(RetainPtr<Socket>&& socket, SocketRole role) FileDescriptor::~FileDescriptor() { + if (m_socket) { + m_socket->close(m_socket_role); + m_socket = nullptr; + } if (m_device) { m_device->close(); m_device = nullptr; @@ -364,6 +369,7 @@ Region* FileDescriptor::mmap(Process& process, LinearAddress laddr, size_t offse // FIXME: Implement mapping at a client-specified address. Most of the support is already in plcae. ASSERT(laddr.as_ptr() == nullptr); auto* region = process.allocate_file_backed_region(LinearAddress(), size, inode(), move(region_name), prot & PROT_READ, prot & PROT_WRITE); + region->page_in(); return region; } diff --git a/Kernel/KeyCode.h b/Kernel/KeyCode.h index 52449dc0a7..4394bd2f60 100644 --- a/Kernel/KeyCode.h +++ b/Kernel/KeyCode.h @@ -108,3 +108,20 @@ enum KeyCode : byte { Key_Tilde, Key_Backtick, }; + +enum KeyModifier { + Mod_Alt = 0x01, + Mod_Ctrl = 0x02, + Mod_Shift = 0x04, + Is_Press = 0x80, +}; + +struct KeyEvent { + KeyCode key { Key_Invalid }; + byte character { 0 }; + byte flags { 0 }; + bool alt() const { return flags & Mod_Alt; } + bool ctrl() const { return flags & Mod_Ctrl; } + bool shift() const { return flags & Mod_Shift; } + bool is_press() const { return flags & Is_Press; } +}; diff --git a/Kernel/Keyboard.h b/Kernel/Keyboard.h index 35bda98164..ff49fdd5d0 100644 --- a/Kernel/Keyboard.h +++ b/Kernel/Keyboard.h @@ -12,22 +12,7 @@ class KeyboardClient; class Keyboard final : public IRQHandler, public CharacterDevice { AK_MAKE_ETERNAL public: - enum Modifier { - Mod_Alt = 0x01, - Mod_Ctrl = 0x02, - Mod_Shift = 0x04, - Is_Press = 0x80, - }; - - struct Event { - KeyCode key { Key_Invalid }; - byte character { 0 }; - byte flags { 0 }; - bool alt() const { return flags & Mod_Alt; } - bool ctrl() const { return flags & Mod_Ctrl; } - bool shift() const { return flags & Mod_Shift; } - bool is_press() const { return flags & Is_Press; } - }; + using Event = KeyEvent; [[gnu::pure]] static Keyboard& the(); diff --git a/Kernel/LocalSocket.cpp b/Kernel/LocalSocket.cpp index 8d7a1f171c..cfc9e23d95 100644 --- a/Kernel/LocalSocket.cpp +++ b/Kernel/LocalSocket.cpp @@ -106,37 +106,54 @@ bool LocalSocket::connect(const sockaddr* address, socklen_t address_size, int& return true; } +void LocalSocket::close(SocketRole role) +{ + if (role == SocketRole::Accepted) + m_server_closed = true; + else if (role == SocketRole::Connected) + m_client_closed = true; +} + bool LocalSocket::can_read(SocketRole role) const { if (m_bound && is_listening()) return can_accept(); if (role == SocketRole::Accepted) - return !m_for_server.is_empty(); - else - return !m_for_client.is_empty(); + return m_client_closed || !m_for_server.is_empty(); + else if (role == SocketRole::Connected) + return m_server_closed || !m_for_client.is_empty(); + ASSERT_NOT_REACHED(); } ssize_t LocalSocket::read(SocketRole role, byte* buffer, size_t size) { if (role == SocketRole::Accepted) return m_for_server.read(buffer, size); - else + else if (role == SocketRole::Connected) return m_for_client.read(buffer, size); + ASSERT_NOT_REACHED(); } ssize_t LocalSocket::write(SocketRole role, const byte* data, size_t size) { - if (role == SocketRole::Accepted) + if (role == SocketRole::Accepted) { + if (m_client_closed) + return -EPIPE; return m_for_client.write(data, size); - else + } else if (role == SocketRole::Connected) { + if (m_client_closed) + return -EPIPE; return m_for_server.write(data, size); + } + ASSERT_NOT_REACHED(); } bool LocalSocket::can_write(SocketRole role) const { if (role == SocketRole::Accepted) - return m_for_client.bytes_in_write_buffer() < 4096; - else - return m_for_server.bytes_in_write_buffer() < 4096; + return m_client_closed || m_for_client.bytes_in_write_buffer() < 4096; + else if (role == SocketRole::Connected) + return m_server_closed || m_for_server.bytes_in_write_buffer() < 4096; + ASSERT_NOT_REACHED(); } diff --git a/Kernel/LocalSocket.h b/Kernel/LocalSocket.h index f4581a67a0..a56d42d7df 100644 --- a/Kernel/LocalSocket.h +++ b/Kernel/LocalSocket.h @@ -13,7 +13,7 @@ public: virtual bool bind(const sockaddr*, socklen_t, int& error) override; virtual bool connect(const sockaddr*, socklen_t, int& error) override; virtual bool get_address(sockaddr*, socklen_t*) override; - + virtual void close(SocketRole) override; virtual bool can_read(SocketRole) const override; virtual ssize_t read(SocketRole, byte*, size_t) override; virtual ssize_t write(SocketRole, const byte*, size_t) override; @@ -27,6 +27,8 @@ private: RetainPtr<LocalSocket> m_peer; bool m_bound { false }; + bool m_server_closed { false }; + bool m_client_closed { false }; sockaddr_un m_address; DoubleBuffer m_for_client; diff --git a/Kernel/Makefile b/Kernel/Makefile index f74cbb6740..b3e36ab606 100644 --- a/Kernel/Makefile +++ b/Kernel/Makefile @@ -51,26 +51,6 @@ VFS_OBJS = \ FileDescriptor.o \ SyntheticFileSystem.o -SHAREDGRAPHICS_OBJS = \ - ../SharedGraphics/Rect.o \ - ../SharedGraphics/Painter.o \ - ../SharedGraphics/Font.o \ - ../SharedGraphics/Color.o \ - ../SharedGraphics/CharacterBitmap.o \ - ../SharedGraphics/GraphicsBitmap.o - -WINDOWSERVER_OBJS = \ - ../WindowServer/WSMessageReceiver.o \ - ../WindowServer/WSMessageLoop.o \ - ../WindowServer/WSWindow.o \ - ../WindowServer/WSWindowManager.o \ - ../WindowServer/WSScreen.o \ - ../WindowServer/WSMenuBar.o \ - ../WindowServer/WSMenu.o \ - ../WindowServer/WSMenuItem.o \ - ../WindowServer/WSClientConnection.o \ - ../WindowServer/main.o - AK_OBJS = \ ../AK/String.o \ ../AK/StringImpl.o \ @@ -78,7 +58,7 @@ AK_OBJS = \ ../AK/FileSystemPath.o \ ../AK/StdLibExtras.o -OBJS = $(KERNEL_OBJS) $(VFS_OBJS) $(AK_OBJS) $(WINDOWSERVER_OBJS) $(SHAREDGRAPHICS_OBJS) +OBJS = $(KERNEL_OBJS) $(VFS_OBJS) $(AK_OBJS) NASM = nasm KERNEL = kernel @@ -89,7 +69,7 @@ STANDARD_FLAGS = -std=c++17 -nostdinc++ -nostdlib -nostdinc KERNEL_FLAGS = -ffreestanding -fno-stack-protector -fno-ident -fno-builtin WARNING_FLAGS = -Wextra -Wall -Wundef -Wcast-qual -Wwrite-strings -Wimplicit-fallthrough FLAVOR_FLAGS = -mregparm=3 -march=i386 -m32 -fno-exceptions -fno-rtti -fmerge-all-constants -fno-unroll-loops -fno-pie -fno-pic -OPTIMIZATION_FLAGS = -Oz -fno-asynchronous-unwind-tables -fno-omit-frame-pointer +OPTIMIZATION_FLAGS = -Os -fno-asynchronous-unwind-tables -fno-omit-frame-pointer INCLUDE_FLAGS = -I.. -I. #SUGGEST_FLAGS = -Wsuggest-final-types -Wsuggest-final-methods -Wsuggest-override #-Wsuggest-attribute=noreturn diff --git a/Kernel/MemoryManager.cpp b/Kernel/MemoryManager.cpp index fc981fe86a..a5b63b4388 100644 --- a/Kernel/MemoryManager.cpp +++ b/Kernel/MemoryManager.cpp @@ -581,9 +581,12 @@ bool MemoryManager::validate_user_write(const Process& process, LinearAddress la RetainPtr<Region> Region::clone() { - InterruptDisabler disabler; - if (m_shared || (m_readable && !m_writable)) { + dbgprintf("%s<%u> Region::clone(): sharing %s (L%x)\n", + current->name().characters(), + current->pid(), + m_name.characters(), + laddr().get()); // Create a new region backed by the same VMObject. return adopt(*new Region(laddr(), size(), m_vmo.copy_ref(), m_offset_in_vmo, String(m_name), m_readable, m_writable)); } diff --git a/Kernel/MemoryManager.h b/Kernel/MemoryManager.h index 0cdd526a0f..289baf0675 100644 --- a/Kernel/MemoryManager.h +++ b/Kernel/MemoryManager.h @@ -142,6 +142,7 @@ public: const VMObject& vmo() const { return *m_vmo; } VMObject& vmo() { return *m_vmo; } + bool is_shared() const { return m_shared; } void set_shared(bool shared) { m_shared = shared; } bool is_bitmap() const { return m_is_bitmap; } diff --git a/Kernel/Process.cpp b/Kernel/Process.cpp index 1060cf7021..16010cf9f7 100644 --- a/Kernel/Process.cpp +++ b/Kernel/Process.cpp @@ -18,16 +18,17 @@ #include "Scheduler.h" #include "FIFO.h" #include "KSyms.h" -#include <WindowServer/WSMessageLoop.h> #include <Kernel/Socket.h> #include "MasterPTY.h" #include "elf.h" +#include <AK/StringBuilder.h> //#define DEBUG_IO //#define TASK_DEBUG //#define FORK_DEBUG #define SIGNAL_DEBUG #define MAX_PROCESS_GIDS 32 +//#define SHARED_BUFFER_DEBUG static const dword default_kernel_stack_size = 16384; static const dword default_userspace_stack_size = 65536; @@ -49,7 +50,6 @@ void Process::initialize() s_hostname = new String("courage"); s_hostname_lock = new Lock; Scheduler::initialize(); - new WSMessageLoop; } Vector<pid_t> Process::all_pids() @@ -167,11 +167,11 @@ void* Process::sys$mmap(const Syscall::SC_mmap_params* params) if ((dword)addr & ~PAGE_MASK) return (void*)-EINVAL; if (flags & MAP_ANONYMOUS) { - // FIXME: Implement mapping at a client-specified address. Most of the support is already in plcae. - ASSERT(addr == nullptr); - auto* region = allocate_region(LinearAddress(), size, "mmap", prot & PROT_READ, prot & PROT_WRITE, false); + auto* region = allocate_region(LinearAddress((dword)addr), size, "mmap", prot & PROT_READ, prot & PROT_WRITE, false); if (!region) return (void*)-ENOMEM; + if (flags & MAP_SHARED) + region->set_shared(true); return region->laddr().as_ptr(); } if (offset & ~PAGE_MASK) @@ -184,6 +184,8 @@ void* Process::sys$mmap(const Syscall::SC_mmap_params* params) auto* region = descriptor->mmap(*this, LinearAddress((dword)addr), offset, size, prot); if (!region) return (void*)-ENOMEM; + if (flags & MAP_SHARED) + region->set_shared(true); return region->laddr().as_ptr(); } @@ -191,9 +193,9 @@ int Process::sys$munmap(void* addr, size_t size) { auto* region = region_from_range(LinearAddress((dword)addr), size); if (!region) - return -1; + return -EINVAL; if (!deallocate_region(*region)) - return -1; + return -EINVAL; return 0; } @@ -2136,9 +2138,6 @@ void Process::finalize() { ASSERT(current == g_finalizer); - if (WSMessageLoop::the().running()) - WSMessageLoop::the().notify_client_died(gui_client_id()); - m_fds.clear(); m_tty = nullptr; disown_all_shared_buffers(); @@ -2367,13 +2366,17 @@ struct SharedBuffer { { if (m_pid1 == process.pid()) { ++m_pid1_retain_count; - if (!m_pid1_region) + if (!m_pid1_region) { m_pid1_region = process.allocate_region_with_vmo(LinearAddress(), size(), m_vmo.copy_ref(), 0, "SharedBuffer", true, true); + m_pid1_region->set_shared(true); + } return m_pid1_region->laddr().as_ptr(); } else if (m_pid2 == process.pid()) { ++m_pid2_retain_count; - if (!m_pid2_region) + if (!m_pid2_region) { m_pid2_region = process.allocate_region_with_vmo(LinearAddress(), size(), m_vmo.copy_ref(), 0, "SharedBuffer", true, true); + m_pid2_region->set_shared(true); + } return m_pid2_region->laddr().as_ptr(); } return nullptr; @@ -2445,7 +2448,9 @@ void SharedBuffer::destroy_if_unused() { if (!m_pid1_retain_count && !m_pid2_retain_count) { LOCKER(shared_buffers().lock()); - kprintf("Destroying unused SharedBuffer{%p} (pid1: %d, pid2: %d)\n", this, m_pid1, m_pid2); +#ifdef SHARED_BUFFER_DEBUG + dbgprintf("Destroying unused SharedBuffer{%p} (pid1: %d, pid2: %d)\n", this, m_pid1, m_pid2); +#endif shared_buffers().resource().remove(m_shared_buffer_id); } } @@ -2474,7 +2479,11 @@ int Process::sys$create_shared_buffer(pid_t peer_pid, size_t size, void** buffer int shared_buffer_id = ++s_next_shared_buffer_id; auto shared_buffer = make<SharedBuffer>(m_pid, peer_pid, size); shared_buffer->m_pid1_region = allocate_region_with_vmo(LinearAddress(), shared_buffer->size(), shared_buffer->m_vmo.copy_ref(), 0, "SharedBuffer", true, true); + shared_buffer->m_pid1_region->set_shared(true); *buffer = shared_buffer->m_pid1_region->laddr().as_ptr(); +#ifdef SHARED_BUFFER_DEBUG + dbgprintf("%s(%u): Created shared buffer %d (%u bytes, vmo is %u) for sharing with %d\n", name().characters(), pid(),shared_buffer_id, size, shared_buffer->size(), peer_pid); +#endif shared_buffers().resource().set(shared_buffer_id, move(shared_buffer)); return shared_buffer_id; } @@ -2486,6 +2495,9 @@ int Process::sys$release_shared_buffer(int shared_buffer_id) if (it == shared_buffers().resource().end()) return -EINVAL; auto& shared_buffer = *(*it).value; +#ifdef SHARED_BUFFER_DEBUG + dbgprintf("%s(%u): Releasing shared buffer %d\n", name().characters(), pid(), shared_buffer_id); +#endif shared_buffer.release(*this); return 0; } @@ -2499,5 +2511,8 @@ void* Process::sys$get_shared_buffer(int shared_buffer_id) auto& shared_buffer = *(*it).value; if (shared_buffer.pid1() != m_pid && shared_buffer.pid2() != m_pid) return (void*)-EINVAL; +#ifdef SHARED_BUFFER_DEBUG + dbgprintf("%s(%u): Retaining shared buffer %d\n", name().characters(), pid(), shared_buffer_id); +#endif return shared_buffer.retain(*this); } diff --git a/Kernel/Process.h b/Kernel/Process.h index e6c18a431d..b4f4ac2335 100644 --- a/Kernel/Process.h +++ b/Kernel/Process.h @@ -48,9 +48,6 @@ struct DisplayInfo { class Process : public InlineLinkedListNode<Process>, public Weakable<Process> { friend class InlineLinkedListNode<Process>; - friend class WSWindowManager; // FIXME: Make a better API for allocate_region(). - friend class GraphicsBitmap; // FIXME: Make a better API for allocate_region(). - friend class Font; //FIXME: This is beyond gross. public: static Process* create_kernel_process(String&& name, void (*entry)()); static Process* create_user_process(const String& path, uid_t, gid_t, pid_t ppid, int& error, Vector<String>&& arguments = Vector<String>(), Vector<String>&& environment = Vector<String>(), TTY* = nullptr); diff --git a/Kernel/Socket.h b/Kernel/Socket.h index f042661c91..0f5f5d11a5 100644 --- a/Kernel/Socket.h +++ b/Kernel/Socket.h @@ -28,7 +28,7 @@ public: virtual bool connect(const sockaddr*, socklen_t, int& error) = 0; virtual bool get_address(sockaddr*, socklen_t*) = 0; virtual bool is_local() const { return false; } - + virtual void close(SocketRole) = 0; virtual bool can_read(SocketRole) const = 0; virtual ssize_t read(SocketRole, byte*, size_t) = 0; virtual ssize_t write(SocketRole, const byte*, size_t) = 0; diff --git a/Kernel/init.cpp b/Kernel/init.cpp index c26c372adc..d3a356097e 100644 --- a/Kernel/init.cpp +++ b/Kernel/init.cpp @@ -25,9 +25,9 @@ #include "BochsVGADevice.h" //#define SPAWN_GUITEST -#define SPAWN_LAUNCHER +//#define SPAWN_LAUNCHER //#define SPAWN_GUITEST2 -#define SPAWN_FILE_MANAGER +//#define SPAWN_FILE_MANAGER //#define SPAWN_FONTEDITOR //#define SPAWN_MULTIPLE_SHELLS //#define STRESS_TEST_SPAWNING @@ -101,6 +101,10 @@ VFS* vfs; int error; + Process::create_user_process("/bin/WindowServer", (uid_t)100, (gid_t)100, (pid_t)0, error, { }, { }, tty0); + if (error != 0) { + dbgprintf("error: %d\n", error); + } //Process::create_user_process("/bin/sh", (uid_t)100, (gid_t)100, (pid_t)0, error, { }, move(environment), tty0); Process::create_user_process("/bin/Terminal", (uid_t)100, (gid_t)100, (pid_t)0, error, { }, { }, tty0); #ifdef SPAWN_GUITEST @@ -128,9 +132,6 @@ VFS* vfs; Process::create_kernel_process("spawn_stress", spawn_stress); #endif - extern void WindowServer_main(); - Process::create_kernel_process("WindowServer", WindowServer_main); - current->sys$exit(0); ASSERT_NOT_REACHED(); } diff --git a/Kernel/makeall.sh b/Kernel/makeall.sh index 911756622f..5dd42bc9dd 100755 --- a/Kernel/makeall.sh +++ b/Kernel/makeall.sh @@ -10,6 +10,8 @@ $make_cmd -C ../LibGUI clean && \ $make_cmd -C ../LibGUI && \ $make_cmd -C ../Userland clean && \ $make_cmd -C ../Userland && \ +$make_cmd -C ../WindowServer clean && \ +$make_cmd -C ../WindowServer && \ $make_cmd -C ../Applications/Terminal clean && \ $make_cmd -C ../Applications/Terminal && \ $make_cmd -C ../Applications/FontEditor clean && \ diff --git a/Kernel/sync.sh b/Kernel/sync.sh index d73c1770c3..6698da8239 100755 --- a/Kernel/sync.sh +++ b/Kernel/sync.sh @@ -69,6 +69,7 @@ cp -v ../Applications/Launcher/Launcher mnt/bin/Launcher cp -v ../Applications/Clock/Clock mnt/bin/Clock cp -v ../Applications/FileManager/FileManager mnt/bin/FileManager cp -v ../Applications/About/About mnt/bin/About +cp -v ../WindowServer/WindowServer mnt/bin/WindowServer cp -v kernel.map mnt/ sh sync-local.sh umount mnt diff --git a/LibC/Makefile b/LibC/Makefile index 17842a7f7c..dc69f3ce10 100644 --- a/LibC/Makefile +++ b/LibC/Makefile @@ -57,7 +57,7 @@ STANDARD_FLAGS = -std=c++17 -nostdinc++ -nostdlib -nostdinc LIBC_FLAGS = -ffreestanding -fno-stack-protector -fno-ident WARNING_FLAGS = -Wextra -Wall -Wundef -Wcast-qual -Wwrite-strings -Wimplicit-fallthrough FLAVOR_FLAGS = -fomit-frame-pointer -march=i386 -m32 -fno-exceptions -fno-rtti -ffunction-sections -fdata-sections -fmerge-all-constants -fno-unroll-loops -fno-pie -fno-pic -OPTIMIZATION_FLAGS = -O2 -fno-asynchronous-unwind-tables +OPTIMIZATION_FLAGS = -Os -fno-asynchronous-unwind-tables INCLUDE_FLAGS = -I.. -I. DEFINES = -DSERENITY -DUSERLAND -DSANITIZE_PTRS diff --git a/LibC/errno_numbers.h b/LibC/errno_numbers.h index b296dddf49..99fff5337a 100644 --- a/LibC/errno_numbers.h +++ b/LibC/errno_numbers.h @@ -47,6 +47,7 @@ __ERROR(EWHYTHO, "Failed without setting an error code (Bug!)") \ __ERROR(ENOTEMPTY, "Directory not empty") \ __ERROR(ECONNREFUSED, "Connection refused") \ + __ERROR(EMAXERRNO, "The highest errno +1 :^)") enum __errno_values { diff --git a/LibC/unistd.cpp b/LibC/unistd.cpp index 39d18b32e5..d6ec950f7d 100644 --- a/LibC/unistd.cpp +++ b/LibC/unistd.cpp @@ -357,7 +357,11 @@ int create_shared_buffer(pid_t peer_pid, size_t size, void** buffer) void* get_shared_buffer(int shared_buffer_id) { int rc = syscall(SC_get_shared_buffer, shared_buffer_id); - __RETURN_WITH_ERRNO(rc, (void*)rc, (void*)-1); + if (rc < 0 && -rc < EMAXERRNO) { + errno = -rc; + return (void*)-1; + } + return (void*)rc; } int release_shared_buffer(int shared_buffer_id) diff --git a/LibGUI/GEventLoop.cpp b/LibGUI/GEventLoop.cpp index 843c5144fb..d13dfa4c88 100644 --- a/LibGUI/GEventLoop.cpp +++ b/LibGUI/GEventLoop.cpp @@ -40,7 +40,7 @@ GEventLoop::GEventLoop() address.sun_family = AF_LOCAL; strcpy(address.sun_path, "/wsportal"); - int retries = 10; + int retries = 1000; int rc = 0; while (retries) { rc = connect(m_event_fd, (const sockaddr*)&address, sizeof(address)); @@ -53,6 +53,7 @@ GEventLoop::GEventLoop() if (rc < 0) { ASSERT_NOT_REACHED(); } + dbgprintf("(%u) GEventLoop constructed :)\n", getpid()); } GEventLoop::~GEventLoop() diff --git a/LibGUI/GWidget.cpp b/LibGUI/GWidget.cpp index 58bdd25a59..01605b611d 100644 --- a/LibGUI/GWidget.cpp +++ b/LibGUI/GWidget.cpp @@ -7,6 +7,8 @@ #include <SharedGraphics/GraphicsBitmap.h> #include <SharedGraphics/Painter.h> +#include <unistd.h> + GWidget::GWidget(GWidget* parent) : GObject(parent) { @@ -72,7 +74,9 @@ void GWidget::handle_paint_event(GPaintEvent& event) Painter painter(*this); painter.fill_rect(event.rect(), background_color()); } + dbgprintf("GWidget{%p} handle_paint_event %s before calling paint_event()\n", this, event.rect().to_string().characters()); paint_event(event); + dbgprintf("GWidget{%p} handle_paint_event %s after calling paint_event()\n", this, event.rect().to_string().characters()); for (auto* ch : children()) { auto* child = (GWidget*)ch; if (child->relative_rect().intersects(event.rect())) { diff --git a/SharedGraphics/Font.cpp b/SharedGraphics/Font.cpp index 7191ae0d30..70e6a5d9dd 100644 --- a/SharedGraphics/Font.cpp +++ b/SharedGraphics/Font.cpp @@ -3,20 +3,11 @@ #include <AK/BufferStream.h> #include <AK/StdLibExtras.h> -#ifdef KERNEL -#include <Kernel/Process.h> -#include <Kernel/MemoryManager.h> -#include <Kernel/FileDescriptor.h> -#include <Kernel/VirtualFileSystem.h> -#endif - -#ifdef USERLAND #include <LibC/unistd.h> #include <LibC/stdio.h> #include <LibC/fcntl.h> #include <LibC/errno.h> #include <LibC/mman.h> -#endif static const byte error_glyph_width = 8; static const byte error_glyph_height = 10; @@ -54,19 +45,7 @@ Font& Font::default_font() { static const char* default_font_path = "/res/fonts/LizaRegular8x10.font"; if (!s_default_font) { -#ifdef USERLAND s_default_font = Font::load_from_file(default_font_path).leak_ref(); -#else - int error; - auto descriptor = VFS::the().open(default_font_path, error, 0, 0, *VFS::the().root_inode()); - if (!descriptor) { - kprintf("Failed to open default font (%s)\n", default_font_path); - ASSERT_NOT_REACHED(); - } - auto* region = current->allocate_file_backed_region(LinearAddress(), font_file_size(10), descriptor->inode(), "default_font", /*readable*/true, /*writable*/false); - ASSERT(region); - s_default_font = Font::load_from_memory(region->laddr().as_ptr()).leak_ref(); -#endif ASSERT(s_default_font); } return *s_default_font; @@ -76,19 +55,7 @@ Font& Font::default_bold_font() { static const char* default_bold_font_path = "/res/fonts/LizaBold8x10.font"; if (!s_default_bold_font) { -#ifdef USERLAND s_default_bold_font = Font::load_from_file(default_bold_font_path).leak_ref(); -#else - int error; - auto descriptor = VFS::the().open(default_bold_font_path, error, 0, 0, *VFS::the().root_inode()); - if (!descriptor) { - kprintf("Failed to open default bold font (%s)\n", default_bold_font_path); - ASSERT_NOT_REACHED(); - } - auto* region = current->allocate_file_backed_region(LinearAddress(), font_file_size(10), descriptor->inode(), "default_bold_font", /*readable*/true, /*writable*/false); - ASSERT(region); - s_default_bold_font = Font::load_from_memory(region->laddr().as_ptr()).leak_ref(); -#endif ASSERT(s_default_bold_font); } return *s_default_bold_font; @@ -116,6 +83,10 @@ Font::Font(const String& name, unsigned* rows, byte glyph_width, byte glyph_heig Font::~Font() { + if (m_mmap_ptr) { + int rc = munmap(m_mmap_ptr, 4096 * 3); + ASSERT(rc == 0); + } } RetainPtr<Font> Font::load_from_memory(const byte* data) @@ -134,7 +105,6 @@ RetainPtr<Font> Font::load_from_memory(const byte* data) return adopt(*new Font(String(header.name), rows, header.glyph_width, header.glyph_height)); } -#ifdef USERLAND RetainPtr<Font> Font::load_from_file(const String& path) { int fd = open(path.characters(), O_RDONLY, 0644); @@ -152,6 +122,7 @@ RetainPtr<Font> Font::load_from_file(const String& path) } auto font = load_from_memory(mapped_file); + font->m_mmap_ptr = mapped_file; int rc = close(fd); ASSERT(rc == 0); @@ -189,4 +160,3 @@ bool Font::write_to_file(const String& path) ASSERT(rc == 0); return true; } -#endif diff --git a/SharedGraphics/Font.h b/SharedGraphics/Font.h index 804d917000..05d89739fb 100644 --- a/SharedGraphics/Font.h +++ b/SharedGraphics/Font.h @@ -47,10 +47,8 @@ public: static RetainPtr<Font> load_from_memory(const byte*); -#ifdef USERLAND static RetainPtr<Font> load_from_file(const String& path); bool write_to_file(const String& path); -#endif ~Font(); @@ -69,6 +67,7 @@ private: String m_name; unsigned* m_rows { nullptr }; + void* m_mmap_ptr { nullptr }; RetainPtr<CharacterBitmap> m_error_bitmap; diff --git a/SharedGraphics/GraphicsBitmap.cpp b/SharedGraphics/GraphicsBitmap.cpp index 19cdd93f56..74ad96672c 100644 --- a/SharedGraphics/GraphicsBitmap.cpp +++ b/SharedGraphics/GraphicsBitmap.cpp @@ -1,18 +1,9 @@ #include "GraphicsBitmap.h" - -#ifdef KERNEL -#include <Kernel/Process.h> -#include <Kernel/MemoryManager.h> -#include <WindowServer/WSMessageLoop.h> -#endif - -#ifdef USERLAND #include <sys/mman.h> #include <unistd.h> #include <fcntl.h> #include <errno.h> #include <stdio.h> -#endif RetainPtr<GraphicsBitmap> GraphicsBitmap::create(const Size& size) { @@ -23,18 +14,9 @@ GraphicsBitmap::GraphicsBitmap(const Size& size) : m_size(size) , m_pitch(size.width() * sizeof(RGBA32)) { -#ifdef KERNEL - Syscall::SC_mmap_params params; - memset(¶ms, 0, sizeof(params)); - params.fd = 0; - params.prot = PROT_READ | PROT_WRITE; - params.flags = MAP_ANONYMOUS | MAP_PRIVATE; - params.size = size.area() * sizeof(RGBA32); - params.offset = 0; - m_data = (RGBA32*)current->sys$mmap(¶ms); + m_data = (RGBA32*)mmap(nullptr, size.area() * sizeof(RGBA32), PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, 0, 0); ASSERT(m_data && m_data != (void*)-1); m_mmaped = true; -#endif } RetainPtr<GraphicsBitmap> GraphicsBitmap::create_wrapper(const Size& size, RGBA32* data) @@ -44,8 +26,6 @@ RetainPtr<GraphicsBitmap> GraphicsBitmap::create_wrapper(const Size& size, RGBA3 RetainPtr<GraphicsBitmap> GraphicsBitmap::load_from_file(const String& path, const Size& size) { - RGBA32* mapped_data = nullptr; -#ifdef USERLAND int fd = open(path.characters(), O_RDONLY, 0644); if (fd < 0) { dbgprintf("open(%s) got fd=%d, failed: %s\n", path.characters(), fd, strerror(errno)); @@ -53,35 +33,17 @@ RetainPtr<GraphicsBitmap> GraphicsBitmap::load_from_file(const String& path, con return nullptr; } - mapped_data = (RGBA32*)mmap(nullptr, size.area() * 4, PROT_READ, MAP_SHARED, fd, 0); + auto* mapped_data = (RGBA32*)mmap(nullptr, size.area() * 4, PROT_READ, MAP_SHARED, fd, 0); if (mapped_data == MAP_FAILED) { int rc = close(fd); ASSERT(rc == 0); return nullptr; } -#else - int error; - auto descriptor = VFS::the().open(path, error, 0, 0, *VFS::the().root_inode()); - if (!descriptor) { - kprintf("Failed to load GraphicsBitmap from file (%s)\n", path.characters()); - return nullptr; - } - auto* region = WSMessageLoop::the().server_process().allocate_file_backed_region(LinearAddress(), size.area() * 4, descriptor->inode(), ".rgb file", /*readable*/true, /*writable*/false); - mapped_data = (RGBA32*)region->laddr().get(); -#endif - -#ifdef USERLAND int rc = close(fd); ASSERT(rc == 0); -#endif auto bitmap = create_wrapper(size, mapped_data); -#ifdef KERNEL - bitmap->m_server_region = region; -#else bitmap->m_mmaped = true; -#endif - return bitmap; } @@ -95,11 +57,7 @@ GraphicsBitmap::GraphicsBitmap(const Size& size, RGBA32* data) RetainPtr<GraphicsBitmap> GraphicsBitmap::create_with_shared_buffer(int shared_buffer_id, const Size& size, RGBA32* data) { if (!data) { -#ifdef KERNEL - void* shared_buffer = current->sys$get_shared_buffer(shared_buffer_id); -#else void* shared_buffer = get_shared_buffer(shared_buffer_id); -#endif if (!shared_buffer || shared_buffer == (void*)-1) return nullptr; data = (RGBA32*)shared_buffer; @@ -118,20 +76,11 @@ GraphicsBitmap::GraphicsBitmap(int shared_buffer_id, const Size& size, RGBA32* d GraphicsBitmap::~GraphicsBitmap() { if (m_mmaped) { -#ifdef KERNEL - int rc = current->sys$munmap(m_data, m_size.area() * 4); -#else int rc = munmap(m_data, m_size.area() * 4); -#endif ASSERT(rc == 0); } if (m_shared_buffer_id != -1) { - int rc; -#ifdef KERNEL - rc = current->sys$release_shared_buffer(m_shared_buffer_id); -#else - rc = release_shared_buffer(m_shared_buffer_id); -#endif + int rc = release_shared_buffer(m_shared_buffer_id); ASSERT(rc == 0); } m_data = nullptr; diff --git a/SharedGraphics/GraphicsBitmap.h b/SharedGraphics/GraphicsBitmap.h index ec36b53d0f..1a29dbe965 100644 --- a/SharedGraphics/GraphicsBitmap.h +++ b/SharedGraphics/GraphicsBitmap.h @@ -7,8 +7,6 @@ #include <AK/RetainPtr.h> #include <AK/AKString.h> -class Region; - class GraphicsBitmap : public Retainable<GraphicsBitmap> { public: static RetainPtr<GraphicsBitmap> create(const Size&); @@ -25,17 +23,10 @@ public: int width() const { return m_size.width(); } int height() const { return m_size.height(); } size_t pitch() const { return m_pitch; } - -#ifdef KERNEL - Region* server_region() { return m_server_region; } -#endif - int shared_buffer_id() const { return m_shared_buffer_id; } private: -#ifdef KERNEL GraphicsBitmap(const Size&); -#endif GraphicsBitmap(const Size&, RGBA32*); GraphicsBitmap(int shared_buffer_id, const Size&, RGBA32*); @@ -44,10 +35,6 @@ private: size_t m_pitch { 0 }; bool m_mmaped { false }; int m_shared_buffer_id { -1 }; - -#ifdef KERNEL - Region* m_server_region { nullptr }; -#endif }; inline RGBA32* GraphicsBitmap::scanline(int y) diff --git a/SharedGraphics/Painter.cpp b/SharedGraphics/Painter.cpp index 96676e0746..b811755d14 100644 --- a/SharedGraphics/Painter.cpp +++ b/SharedGraphics/Painter.cpp @@ -4,7 +4,7 @@ #include <AK/Assertions.h> #include <AK/StdLibExtras.h> -#ifdef USERLAND +#ifdef LIBGUI #include <LibGUI/GWidget.h> #include <LibGUI/GWindow.h> #include <LibGUI/GEventLoop.h> @@ -22,7 +22,7 @@ Painter::Painter(GraphicsBitmap& bitmap) m_clip_rect = { { 0, 0 }, bitmap.size() }; } -#ifdef USERLAND +#ifdef LIBGUI Painter::Painter(GWidget& widget) : m_font(&widget.font()) { @@ -30,7 +30,6 @@ Painter::Painter(GWidget& widget) request.type = WSAPI_ClientMessage::Type::GetWindowBackingStore; request.window_id = widget.window()->window_id(); auto response = GEventLoop::main().sync_request(request, WSAPI_ServerMessage::DidGetWindowBackingStore); - m_backing_store_id = response.backing.backing_store_id; m_target = GraphicsBitmap::create_with_shared_buffer(response.backing.shared_buffer_id, response.backing.size); ASSERT(m_target); @@ -50,15 +49,7 @@ Painter::Painter(GWidget& widget) Painter::~Painter() { -#ifdef USERLAND m_target = nullptr; - if (m_backing_store_id) { - WSAPI_ClientMessage request; - request.type = WSAPI_ClientMessage::Type::ReleaseWindowBackingStore; - request.backing.backing_store_id = m_backing_store_id; - GEventLoop::main().post_message_to_server(request); - } -#endif } void Painter::fill_rect_with_draw_op(const Rect& a_rect, Color color) diff --git a/SharedGraphics/Painter.h b/SharedGraphics/Painter.h index 646bf4ee1b..a89c7d0267 100644 --- a/SharedGraphics/Painter.h +++ b/SharedGraphics/Painter.h @@ -11,7 +11,7 @@ class GlyphBitmap; class GraphicsBitmap; class Font; -#ifndef KERNEL +#ifdef USERLAND class GWidget; class GWindow; #endif @@ -20,7 +20,7 @@ enum class TextAlignment { TopLeft, CenterLeft, Center, CenterRight }; class Painter { public: -#ifndef KERNEL +#ifdef USERLAND explicit Painter(GWidget&); #endif explicit Painter(GraphicsBitmap&); @@ -63,9 +63,8 @@ private: Point m_translation; Rect m_clip_rect; RetainPtr<GraphicsBitmap> m_target; -#ifndef KERNEL +#ifdef LIBGUI GWindow* m_window { nullptr }; - void* m_backing_store_id { nullptr }; #endif DrawOp m_draw_op { DrawOp::Copy }; }; diff --git a/WindowServer/.gitignore b/WindowServer/.gitignore index 6142305dc1..7d04c54152 100644 --- a/WindowServer/.gitignore +++ b/WindowServer/.gitignore @@ -1,2 +1,3 @@ *.o *.d +WindowServer diff --git a/WindowServer/Makefile b/WindowServer/Makefile new file mode 100644 index 0000000000..32413c6a7e --- /dev/null +++ b/WindowServer/Makefile @@ -0,0 +1,52 @@ +SHAREDGRAPHICS_OBJS = \ + ../SharedGraphics/Painter.o \ + ../SharedGraphics/Font.o \ + ../SharedGraphics/Rect.o \ + ../SharedGraphics/GraphicsBitmap.o \ + ../SharedGraphics/CharacterBitmap.o \ + ../SharedGraphics/Color.o + +WINDOWSERVER_OBJS = \ + WSMessageReceiver.o \ + WSMessageLoop.o \ + WSWindow.o \ + WSWindowManager.o \ + WSScreen.o \ + WSMenuBar.o \ + WSMenu.o \ + WSMenuItem.o \ + WSClientConnection.o \ + main.o + +APP = WindowServer +OBJS = $(SHAREDGRAPHICS_OBJS) $(WINDOWSERVER_OBJS) + +ARCH_FLAGS = +STANDARD_FLAGS = -std=c++17 -nostdinc++ -nostdlib -nostdinc +USERLAND_FLAGS = -ffreestanding -fno-stack-protector -fno-ident +WARNING_FLAGS = -Wextra -Wall -Wundef -Wcast-qual -Wwrite-strings -Wimplicit-fallthrough +FLAVOR_FLAGS = -march=i386 -m32 -fno-exceptions -fno-rtti -fmerge-all-constants -fno-unroll-loops -fno-pie -fno-pic +OPTIMIZATION_FLAGS = -Oz -fno-asynchronous-unwind-tables +INCLUDE_FLAGS = -I.. -I. -I../LibC + +DEFINES = -DSERENITY -DSANITIZE_PTRS -DUSERLAND + +CXXFLAGS = -MMD -MP $(WARNING_FLAGS) $(OPTIMIZATION_FLAGS) $(USERLAND_FLAGS) $(FLAVOR_FLAGS) $(ARCH_FLAGS) $(STANDARD_FLAGS) $(INCLUDE_FLAGS) $(DEFINES) +CXX = clang +LD = ld +AR = ar +LDFLAGS = -static --strip-debug -melf_i386 -e _start --gc-sections + +all: $(APP) + +$(APP): $(OBJS) + $(LD) -o $(APP) $(LDFLAGS) $(OBJS) ../LibC/LibC.a + +.cpp.o: + @echo "CXX $<"; $(CXX) $(CXXFLAGS) -o $@ -c $< + +-include $(OBJS:%.o=%.d) + +clean: + @echo "CLEAN"; rm -f $(APPS) $(OBJS) *.d + diff --git a/WindowServer/WSAPITypes.h b/WindowServer/WSAPITypes.h index 7c5b4e0541..8f9257c715 100644 --- a/WindowServer/WSAPITypes.h +++ b/WindowServer/WSAPITypes.h @@ -34,7 +34,6 @@ struct WSAPI_WindowParameters { }; struct WSAPI_WindowBackingStoreInfo { - void* backing_store_id; WSAPI_Size size; size_t bpp; size_t pitch; @@ -114,7 +113,6 @@ struct WSAPI_ServerMessage { unsigned identifier; } menu; struct { - void* backing_store_id; WSAPI_Size size; size_t bpp; size_t pitch; @@ -143,7 +141,6 @@ struct WSAPI_ClientMessage { InvalidateRect, DidFinishPainting, GetWindowBackingStore, - ReleaseWindowBackingStore, SetGlobalCursorTracking, }; Type type { Invalid }; @@ -161,9 +158,6 @@ struct WSAPI_ClientMessage { struct { WSAPI_Rect rect; } window; - struct { - void* backing_store_id; - } backing; }; }; diff --git a/WindowServer/WSClientConnection.cpp b/WindowServer/WSClientConnection.cpp index d049994533..320b0edd6a 100644 --- a/WindowServer/WSClientConnection.cpp +++ b/WindowServer/WSClientConnection.cpp @@ -6,16 +6,18 @@ #include <WindowServer/WSWindow.h> #include <WindowServer/WSWindowManager.h> #include <WindowServer/WSAPITypes.h> -#include <Kernel/Process.h> +#include <sys/ioctl.h> +#include <unistd.h> +#include <errno.h> +#include <stdio.h> -Lockable<HashMap<int, WSClientConnection*>>* s_connections; +HashMap<int, WSClientConnection*>* s_connections; void WSClientConnection::for_each_client(Function<void(WSClientConnection&)> callback) { if (!s_connections) return; - LOCKER(s_connections->lock()); - for (auto& it : s_connections->resource()) { + for (auto& it : *s_connections) { callback(*it.value); } } @@ -24,36 +26,29 @@ WSClientConnection* WSClientConnection::from_client_id(int client_id) { if (!s_connections) return nullptr; - LOCKER(s_connections->lock()); - auto it = s_connections->resource().find(client_id); - if (it == s_connections->resource().end()) + auto it = s_connections->find(client_id); + if (it == s_connections->end()) return nullptr; return (*it).value; } -WSClientConnection* WSClientConnection::ensure_for_client_id(int client_id) -{ - if (auto* client = from_client_id(client_id)) - return client; - return new WSClientConnection(client_id); -} - WSClientConnection::WSClientConnection(int fd) : m_fd(fd) { - int rc = current->sys$ioctl(m_fd, 413, (int)&m_pid); + static int s_next_client_id = 0; + m_client_id = ++s_next_client_id; + + int rc = ioctl(m_fd, 413, (int)&m_pid); ASSERT(rc == 0); if (!s_connections) - s_connections = new Lockable<HashMap<int, WSClientConnection*>>; - LOCKER(s_connections->lock()); - s_connections->resource().set(m_client_id, this); + s_connections = new HashMap<int, WSClientConnection*>; + s_connections->set(m_client_id, this); } WSClientConnection::~WSClientConnection() { - LOCKER(s_connections->lock()); - s_connections->resource().remove(m_client_id); + s_connections->remove(m_client_id); } void WSClientConnection::post_error(const String& error_message) @@ -69,14 +64,23 @@ void WSClientConnection::post_error(const String& error_message) void WSClientConnection::post_message(const WSAPI_ServerMessage& message) { - int nwritten = WSMessageLoop::the().server_process().sys$write(m_fd, &message, sizeof(message)); + int nwritten = write(m_fd, &message, sizeof(message)); + if (nwritten < 0) { + if (errno == EPIPE) { + dbgprintf("WSClientConnection::post_message: Disconnected from peer.\n"); + return; + } + perror("WSClientConnection::post_message write"); + ASSERT_NOT_REACHED(); + } + ASSERT(nwritten == sizeof(message)); } -RetainPtr<GraphicsBitmap> WSClientConnection::create_bitmap(const Size& size) +RetainPtr<GraphicsBitmap> WSClientConnection::create_shared_bitmap(const Size& size) { RGBA32* buffer; - int shared_buffer_id = current->sys$create_shared_buffer(m_pid, size.area() * sizeof(RGBA32), (void**)&buffer); + int shared_buffer_id = create_shared_buffer(m_pid, size.area() * sizeof(RGBA32), (void**)&buffer); ASSERT(shared_buffer_id >= 0); ASSERT(buffer); ASSERT(buffer != (void*)-1); @@ -352,13 +356,9 @@ void WSClientConnection::handle_request(WSAPIGetWindowBackingStoreRequest& reque auto& window = *(*it).value; auto* backing_store = window.backing(); - // FIXME: It shouldn't work this way! - backing_store->retain(); - WSAPI_ServerMessage response; response.type = WSAPI_ServerMessage::Type::DidGetWindowBackingStore; response.window_id = window_id; - response.backing.backing_store_id = backing_store; response.backing.bpp = sizeof(RGBA32); response.backing.pitch = backing_store->pitch(); response.backing.size = backing_store->size(); @@ -366,14 +366,6 @@ void WSClientConnection::handle_request(WSAPIGetWindowBackingStoreRequest& reque WSMessageLoop::the().post_message_to_client(request.client_id(), response); } -void WSClientConnection::handle_request(WSAPIReleaseWindowBackingStoreRequest& request) -{ - int backing_store_id = request.backing_store_id(); - // FIXME: It shouldn't work this way! - auto* backing_store = (GraphicsBitmap*)backing_store_id; - backing_store->release(); -} - void WSClientConnection::handle_request(WSAPISetGlobalCursorTrackingRequest& request) { int window_id = request.window_id(); @@ -423,8 +415,6 @@ void WSClientConnection::on_request(WSAPIClientRequest& request) return handle_request(static_cast<WSAPIDidFinishPaintingNotification&>(request)); case WSMessage::APIGetWindowBackingStoreRequest: return handle_request(static_cast<WSAPIGetWindowBackingStoreRequest&>(request)); - case WSMessage::APIReleaseWindowBackingStoreRequest: - return handle_request(static_cast<WSAPIReleaseWindowBackingStoreRequest&>(request)); case WSMessage::APISetGlobalCursorTrackingRequest: return handle_request(static_cast<WSAPISetGlobalCursorTrackingRequest&>(request)); default: diff --git a/WindowServer/WSClientConnection.h b/WindowServer/WSClientConnection.h index e92921150a..f2467c14fd 100644 --- a/WindowServer/WSClientConnection.h +++ b/WindowServer/WSClientConnection.h @@ -19,11 +19,10 @@ public: virtual ~WSClientConnection() override; static WSClientConnection* from_client_id(int client_id); - static WSClientConnection* ensure_for_client_id(int client_id); static void for_each_client(Function<void(WSClientConnection&)>); void post_message(const WSAPI_ServerMessage&); - RetainPtr<GraphicsBitmap> create_bitmap(const Size&); + RetainPtr<GraphicsBitmap> create_shared_bitmap(const Size&); int client_id() const { return m_client_id; } WSMenuBar* app_menubar() { return m_app_menubar.ptr(); } @@ -52,7 +51,6 @@ private: void handle_request(WSAPIInvalidateRectRequest&); void handle_request(WSAPIDidFinishPaintingNotification&); void handle_request(WSAPIGetWindowBackingStoreRequest&); - void handle_request(WSAPIReleaseWindowBackingStoreRequest&); void handle_request(WSAPISetGlobalCursorTrackingRequest&); void post_error(const String&); diff --git a/WindowServer/WSMessage.h b/WindowServer/WSMessage.h index fa38dfba78..fdbd67dbe3 100644 --- a/WindowServer/WSMessage.h +++ b/WindowServer/WSMessage.h @@ -38,7 +38,6 @@ public: APIInvalidateRectRequest, APIDidFinishPaintingNotification, APIGetWindowBackingStoreRequest, - APIReleaseWindowBackingStoreRequest, APISetGlobalCursorTrackingRequest, __End_API_Client_Requests, }; @@ -353,20 +352,6 @@ private: int m_window_id { 0 }; }; -class WSAPIReleaseWindowBackingStoreRequest final : public WSAPIClientRequest { -public: - explicit WSAPIReleaseWindowBackingStoreRequest(int client_id, int backing_store_id) - : WSAPIClientRequest(WSMessage::APIReleaseWindowBackingStoreRequest, client_id) - , m_backing_store_id(backing_store_id) - { - } - - int backing_store_id() const { return m_backing_store_id; } - -private: - int m_backing_store_id { 0 }; -}; - class WSAPIDidFinishPaintingNotification final : public WSAPIClientRequest { public: explicit WSAPIDidFinishPaintingNotification(int client_id, int window_id, const Rect& rect) diff --git a/WindowServer/WSMessageLoop.cpp b/WindowServer/WSMessageLoop.cpp index c9f75bdfba..b49dde17b5 100644 --- a/WindowServer/WSMessageLoop.cpp +++ b/WindowServer/WSMessageLoop.cpp @@ -4,18 +4,21 @@ #include "WSWindowManager.h" #include "WSScreen.h" #include <WindowServer/WSClientConnection.h> -#include "PS2MouseDevice.h" -#include <Kernel/Keyboard.h> +#include <Kernel/KeyCode.h> #include <WindowServer/WSAPITypes.h> -#include <AK/Bitmap.h> -#include "Process.h" +#include <unistd.h> +#include <time.h> +#include <sys/socket.h> +#include <sys/select.h> +#include <fcntl.h> +#include <stdio.h> +#include <errno.h> //#define WSEVENTLOOP_DEBUG static WSMessageLoop* s_the; WSMessageLoop::WSMessageLoop() - : m_lock("WSMessageLoop") { if (!s_the) s_the = this; @@ -33,21 +36,19 @@ WSMessageLoop& WSMessageLoop::the() int WSMessageLoop::exec() { - ASSERT(m_server_process == current); + m_keyboard_fd = open("/dev/keyboard", O_RDONLY | O_NONBLOCK | O_CLOEXEC); + m_mouse_fd = open("/dev/psaux", O_RDONLY | O_NONBLOCK | O_CLOEXEC); - m_keyboard_fd = m_server_process->sys$open("/dev/keyboard", O_RDONLY); - m_mouse_fd = m_server_process->sys$open("/dev/psaux", O_RDONLY); + unlink("/wsportal"); - m_server_process->sys$unlink("/wsportal"); - - m_server_fd = m_server_process->sys$socket(AF_LOCAL, SOCK_STREAM | SOCK_NONBLOCK, 0); + m_server_fd = socket(AF_LOCAL, SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC, 0); ASSERT(m_server_fd >= 0); sockaddr_un address; address.sun_family = AF_LOCAL; strcpy(address.sun_path, "/wsportal"); - int rc = m_server_process->sys$bind(m_server_fd, (const sockaddr*)&address, sizeof(address)); + int rc = bind(m_server_fd, (const sockaddr*)&address, sizeof(address)); ASSERT(rc == 0); - rc = m_server_process->sys$listen(m_server_fd, 5); + rc = listen(m_server_fd, 5); ASSERT(rc == 0); ASSERT(m_keyboard_fd >= 0); @@ -56,13 +57,7 @@ int WSMessageLoop::exec() m_running = true; for (;;) { wait_for_message(); - - Vector<QueuedMessage> messages; - { - ASSERT_INTERRUPTS_ENABLED(); - LOCKER(m_lock); - messages = move(m_queued_messages); - } + Vector<QueuedMessage> messages = move(m_queued_messages); for (auto& queued_message : messages) { auto* receiver = queued_message.receiver; @@ -81,12 +76,6 @@ int WSMessageLoop::exec() } } -Process* WSMessageLoop::process_from_client_id(int client_id) -{ - // FIXME: This shouldn't work this way lol. - return (Process*)client_id; -} - void WSMessageLoop::post_message_to_client(int client_id, const WSAPI_ServerMessage& message) { auto* client = WSClientConnection::from_client_id(client_id); @@ -97,53 +86,16 @@ void WSMessageLoop::post_message_to_client(int client_id, const WSAPI_ServerMess void WSMessageLoop::post_message(WSMessageReceiver* receiver, OwnPtr<WSMessage>&& message) { - LOCKER(m_lock); #ifdef WSEVENTLOOP_DEBUG dbgprintf("WSMessageLoop::post_message: {%u} << receiver=%p, message=%p (type=%u)\n", m_queued_messages.size(), receiver, message.ptr(), message->type()); #endif - -#if 0 - if (message->type() == WSMessage::WM_ClientFinishedPaint) { - auto& invalidation_message = static_cast<WSClientFinishedPaintMessage&>(*message); - for (auto& queued_message : m_queued_messages) { - if (receiver == queued_message.receiver && queued_message.message->type() == WSMessage::WM_ClientFinishedPaint) { - auto& queued_invalidation_message = static_cast<WSClientFinishedPaintMessage&>(*queued_message.message); - if (queued_invalidation_message.rect().is_empty() || queued_invalidation_message.rect().contains(invalidation_message.rect())) { -#ifdef WSEVENTLOOP_DEBUG - dbgprintf("Swallow WM_ClientFinishedPaint\n"); -#endif - return; - } - } - } - } - - if (message->type() == WSMessage::WM_ClientWantsToPaint) { - auto& invalidation_message = static_cast<WSClientWantsToPaintMessage&>(*message); - for (auto& queued_message : m_queued_messages) { - if (receiver == queued_message.receiver && queued_message.message->type() == WSMessage::WM_ClientWantsToPaint) { - auto& queued_invalidation_message = static_cast<WSClientWantsToPaintMessage&>(*queued_message.message); - if (queued_invalidation_message.rect().is_empty() || queued_invalidation_message.rect().contains(invalidation_message.rect())) { -#ifdef WSEVENTLOOP_DEBUG - dbgprintf("Swallow WM_ClientWantsToPaint\n"); -#endif - return; - } - } - } - } -#endif - m_queued_messages.append({ receiver, move(message) }); - - if (current != m_server_process) - m_server_process->request_wakeup(); } void WSMessageLoop::Timer::reload() { struct timeval now; - current->sys$gettimeofday(&now); + gettimeofday(&now, nullptr); next_fire_time = { now.tv_sec + (interval / 1000), now.tv_usec + (interval % 1000) @@ -174,28 +126,22 @@ int WSMessageLoop::stop_timer(int timer_id) void WSMessageLoop::wait_for_message() { fd_set rfds; - memset(&rfds, 0, sizeof(rfds)); - auto bitmap = Bitmap::wrap((byte*)&rfds, FD_SETSIZE); + FD_ZERO(&rfds); int max_fd = 0; - auto add_fd_to_set = [&max_fd] (int fd, auto& bitmap) { - bitmap.set(fd, true); + auto add_fd_to_set = [&max_fd] (int fd, auto& set) { + FD_SET(fd, &set); if (fd > max_fd) max_fd = fd; }; - add_fd_to_set(m_keyboard_fd, bitmap); - add_fd_to_set(m_mouse_fd, bitmap); - add_fd_to_set(m_server_fd, bitmap); + add_fd_to_set(m_keyboard_fd, rfds); + add_fd_to_set(m_mouse_fd, rfds); + add_fd_to_set(m_server_fd, rfds); WSClientConnection::for_each_client([&] (WSClientConnection& client) { - add_fd_to_set(client.fd(), bitmap); + add_fd_to_set(client.fd(), rfds); }); - Syscall::SC_select_params params; - params.nfds = max_fd + 1; - params.readfds = &rfds; - params.writefds = nullptr; - params.exceptfds = nullptr; struct timeval timeout = { 0, 0 }; bool had_any_timer = false; @@ -210,19 +156,13 @@ void WSMessageLoop::wait_for_message() timeout = timer.next_fire_time; } - if (m_timers.is_empty() && m_queued_messages.is_empty()) - params.timeout = nullptr; - else - params.timeout = &timeout; - - int rc = m_server_process->sys$select(¶ms); - memory_barrier(); + int rc = select(max_fd + 1, &rfds, nullptr, nullptr, m_timers.is_empty() && m_queued_messages.is_empty() ? nullptr : &timeout); if (rc < 0) { ASSERT_NOT_REACHED(); } struct timeval now; - current->sys$gettimeofday(&now); + gettimeofday(&now, nullptr); for (auto& it : m_timers) { auto& timer = *it.value; if (now.tv_sec > timer.next_fire_time.tv_sec || (now.tv_sec == timer.next_fire_time.tv_sec && now.tv_usec > timer.next_fire_time.tv_usec)) { @@ -231,30 +171,37 @@ void WSMessageLoop::wait_for_message() } } - if (bitmap.get(m_keyboard_fd)) + if (FD_ISSET(m_keyboard_fd, &rfds)) drain_keyboard(); - if (bitmap.get(m_mouse_fd)) + if (FD_ISSET(m_mouse_fd, &rfds)) drain_mouse(); - if (bitmap.get(m_server_fd)) { + if (FD_ISSET(m_server_fd, &rfds)) { sockaddr_un address; socklen_t address_size = sizeof(address); - int client_fd = m_server_process->sys$accept(m_server_fd, (sockaddr*)&address, &address_size); - kprintf("accept() returned fd=%d, address=%s\n", client_fd, address.sun_path); + int client_fd = accept(m_server_fd, (sockaddr*)&address, &address_size); + dbgprintf("accept() returned fd=%d, address=%s\n", client_fd, address.sun_path); + ASSERT(client_fd >= 0); new WSClientConnection(client_fd); } WSClientConnection::for_each_client([&] (WSClientConnection& client) { - if (bitmap.get(client.fd())) { - for (;;) { - WSAPI_ClientMessage message; - // FIXME: Don't go one message at a time, that's so much context switching, oof. - ssize_t nread = m_server_process->sys$read(client.fd(), &message, sizeof(WSAPI_ClientMessage)); - if (nread == 0) - break; - if (nread < 0) { - ASSERT_NOT_REACHED(); - } - on_receive_from_client(client.client_id(), message); + if (!FD_ISSET(client.fd(), &rfds)) + return; + unsigned messages_received = 0; + for (;;) { + WSAPI_ClientMessage message; + // FIXME: Don't go one message at a time, that's so much context switching, oof. + ssize_t nread = read(client.fd(), &message, sizeof(WSAPI_ClientMessage)); + if (nread == 0) { + if (!messages_received) + notify_client_disconnected(client.client_id()); + break; } + if (nread < 0) { + perror("read"); + ASSERT_NOT_REACHED(); + } + on_receive_from_client(client.client_id(), message); + ++messages_received; } }); } @@ -262,14 +209,17 @@ void WSMessageLoop::wait_for_message() void WSMessageLoop::drain_mouse() { auto& screen = WSScreen::the(); - auto& mouse = PS2MouseDevice::the(); bool prev_left_button = screen.left_mouse_button_pressed(); bool prev_right_button = screen.right_mouse_button_pressed(); int dx = 0; int dy = 0; - while (mouse.can_read(*m_server_process)) { + bool left_button = prev_left_button; + bool right_button = prev_right_button; + for (;;) { byte data[3]; - ssize_t nread = mouse.read(*m_server_process, (byte*)data, sizeof(data)); + ssize_t nread = read(m_mouse_fd, data, sizeof(data)); + if (nread == 0) + break; ASSERT(nread == sizeof(data)); bool left_button = data[0] & 1; bool right_button = data[0] & 2; @@ -290,7 +240,7 @@ void WSMessageLoop::drain_mouse() dx += x; dy += -y; - if (left_button != prev_left_button || right_button != prev_right_button || !mouse.can_read(*m_server_process)) { + if (left_button != prev_left_button || right_button != prev_right_button) { prev_left_button = left_button; prev_right_button = right_button; screen.on_receive_mouse_data(dx, dy, left_button, right_button); @@ -298,23 +248,26 @@ void WSMessageLoop::drain_mouse() dy = 0; } } + if (dx || dy) { + screen.on_receive_mouse_data(dx, dy, left_button, right_button); + } } void WSMessageLoop::drain_keyboard() { auto& screen = WSScreen::the(); - auto& keyboard = Keyboard::the(); - while (keyboard.can_read(*m_server_process)) { - Keyboard::Event event; - ssize_t nread = keyboard.read(*m_server_process, (byte*)&event, sizeof(Keyboard::Event)); - ASSERT(nread == sizeof(Keyboard::Event)); + for (;;) { + KeyEvent event; + ssize_t nread = read(m_keyboard_fd, (byte*)&event, sizeof(KeyEvent)); + if (nread == 0) + break; + ASSERT(nread == sizeof(KeyEvent)); screen.on_receive_keyboard_data(event); } } -void WSMessageLoop::notify_client_died(int client_id) +void WSMessageLoop::notify_client_disconnected(int client_id) { - LOCKER(m_lock); auto* client = WSClientConnection::from_client_id(client_id); if (!client) return; @@ -323,12 +276,14 @@ void WSMessageLoop::notify_client_died(int client_id) void WSMessageLoop::on_receive_from_client(int client_id, const WSAPI_ClientMessage& message) { +#if 0 // FIXME: This should not be necessary.. why is this necessary? while (!running()) - Scheduler::yield(); + sched_yield(); +#endif - LOCKER(m_lock); - WSClientConnection* client = WSClientConnection::ensure_for_client_id(client_id); + WSClientConnection* client = WSClientConnection::from_client_id(client_id); + ASSERT(client); switch (message.type) { case WSAPI_ClientMessage::Type::CreateMenubar: post_message(client, make<WSAPICreateMenubarRequest>(client_id)); @@ -383,9 +338,6 @@ void WSMessageLoop::on_receive_from_client(int client_id, const WSAPI_ClientMess case WSAPI_ClientMessage::Type::GetWindowBackingStore: post_message(client, make<WSAPIGetWindowBackingStoreRequest>(client_id, message.window_id)); break; - case WSAPI_ClientMessage::Type::ReleaseWindowBackingStore: - post_message(client, make<WSAPIReleaseWindowBackingStoreRequest>(client_id, (int)message.backing.backing_store_id)); - break; case WSAPI_ClientMessage::Type::SetGlobalCursorTracking: post_message(client, make<WSAPISetGlobalCursorTrackingRequest>(client_id, message.window_id, message.value)); break; diff --git a/WindowServer/WSMessageLoop.h b/WindowServer/WSMessageLoop.h index 338bf6c63e..0bf69bd461 100644 --- a/WindowServer/WSMessageLoop.h +++ b/WindowServer/WSMessageLoop.h @@ -1,14 +1,12 @@ #pragma once #include "WSMessage.h" -#include <AK/Lock.h> #include <AK/HashMap.h> #include <AK/OwnPtr.h> #include <AK/Vector.h> #include <AK/Function.h> class WSMessageReceiver; -class Process; struct WSAPI_ClientMessage; struct WSAPI_ServerMessage; @@ -24,9 +22,6 @@ public: static WSMessageLoop& the(); bool running() const { return m_running; } - Process& server_process() { return *m_server_process; } - - void set_server_process(Process& process) { m_server_process = &process; } int start_timer(int ms, Function<void()>&&); int stop_timer(int timer_id); @@ -34,23 +29,19 @@ public: void post_message_to_client(int client_id, const WSAPI_ServerMessage&); void on_receive_from_client(int client_id, const WSAPI_ClientMessage&); - static Process* process_from_client_id(int client_id); - void notify_client_died(int client_id); + void notify_client_disconnected(int client_id); private: void wait_for_message(); void drain_mouse(); void drain_keyboard(); - Lock m_lock; - struct QueuedMessage { WSMessageReceiver* receiver { nullptr }; OwnPtr<WSMessage> message; }; Vector<QueuedMessage> m_queued_messages; - Process* m_server_process { nullptr }; bool m_running { false }; int m_keyboard_fd { -1 }; diff --git a/WindowServer/WSMessageReceiver.cpp b/WindowServer/WSMessageReceiver.cpp index 62f1342d43..20508c3005 100644 --- a/WindowServer/WSMessageReceiver.cpp +++ b/WindowServer/WSMessageReceiver.cpp @@ -1,5 +1,4 @@ #include "WSMessageReceiver.h" -#include <AK/Assertions.h> WSMessageReceiver::WSMessageReceiver() { diff --git a/WindowServer/WSScreen.cpp b/WindowServer/WSScreen.cpp index 743bfbba8b..e2e2ce7610 100644 --- a/WindowServer/WSScreen.cpp +++ b/WindowServer/WSScreen.cpp @@ -2,7 +2,6 @@ #include "WSMessageLoop.h" #include "WSMessage.h" #include "WSWindowManager.h" -#include <AK/Assertions.h> static WSScreen* s_the; @@ -61,7 +60,7 @@ void WSScreen::on_receive_mouse_data(int dx, int dy, bool left_button, bool righ WSWindowManager::the().invalidate_cursor(); } -void WSScreen::on_receive_keyboard_data(Keyboard::Event kernel_event) +void WSScreen::on_receive_keyboard_data(KeyEvent kernel_event) { auto message = make<WSKeyEvent>(kernel_event.is_press() ? WSMessage::KeyDown : WSMessage::KeyUp, kernel_event.key, kernel_event.character); message->m_shift = kernel_event.shift(); diff --git a/WindowServer/WSScreen.h b/WindowServer/WSScreen.h index 35f42a1cd1..e9c41373e1 100644 --- a/WindowServer/WSScreen.h +++ b/WindowServer/WSScreen.h @@ -3,7 +3,7 @@ #include <SharedGraphics/Rect.h> #include <SharedGraphics/Size.h> #include <SharedGraphics/Color.h> -#include <Kernel/Keyboard.h> +#include <Kernel/KeyCode.h> class WSScreen { public: @@ -26,7 +26,7 @@ public: bool right_mouse_button_pressed() const { return m_right_mouse_button_pressed; } void on_receive_mouse_data(int dx, int dy, bool left_button, bool right_button); - void on_receive_keyboard_data(Keyboard::Event); + void on_receive_keyboard_data(KeyEvent); protected: WSScreen(unsigned width, unsigned height); diff --git a/WindowServer/WSWindow.cpp b/WindowServer/WSWindow.cpp index 17ead6f47c..ccceaff0de 100644 --- a/WindowServer/WSWindow.cpp +++ b/WindowServer/WSWindow.cpp @@ -47,7 +47,7 @@ void WSWindow::set_rect(const Rect& rect) if (m_menu) m_backing = GraphicsBitmap::create(m_rect.size()); else if (client) - m_backing = client->create_bitmap(m_rect.size()); + m_backing = client->create_shared_bitmap(m_rect.size()); } WSWindowManager::the().notify_rect_changed(*this, old_rect, rect); diff --git a/WindowServer/WSWindowManager.cpp b/WindowServer/WSWindowManager.cpp index cf300bb0da..affa0b844c 100644 --- a/WindowServer/WSWindowManager.cpp +++ b/WindowServer/WSWindowManager.cpp @@ -2,8 +2,6 @@ #include "WSWindow.h" #include "WSScreen.h" #include "WSMessageLoop.h" -#include "Process.h" -#include "MemoryManager.h" #include <SharedGraphics/Font.h> #include <SharedGraphics/Painter.h> #include <SharedGraphics/CharacterBitmap.h> @@ -13,6 +11,9 @@ #include "WSMenuBar.h" #include "WSMenuItem.h" #include <WindowServer/WSClientConnection.h> +#include <sys/ioctl.h> +#include <unistd.h> +#include <stdio.h> #ifdef KERNEL #include <Kernel/ProcFS.h> @@ -79,8 +80,7 @@ static WSWindowManager* s_the; WSWindowManager& WSWindowManager::the() { - if (!s_the) - s_the = new WSWindowManager; + ASSERT(s_the); return *s_the; } @@ -130,7 +130,7 @@ void WSWindowManager::flip_buffers() swap(m_front_painter, m_back_painter); if (m_framebuffer_fd != -1) { int new_y_offset = m_buffers_are_flipped ? 0 : m_screen_rect.height(); - int rc = current->sys$ioctl(m_framebuffer_fd, 1982, new_y_offset); + int rc = ioctl(m_framebuffer_fd, 1982, new_y_offset); ASSERT(rc == 0); } m_buffers_are_flipped = !m_buffers_are_flipped; @@ -139,9 +139,10 @@ void WSWindowManager::flip_buffers() WSWindowManager::WSWindowManager() : m_screen(WSScreen::the()) , m_screen_rect(m_screen.rect()) - , m_lock("WSWindowManager") , m_flash_flush(false) { + s_the = this; + #ifndef DEBUG_COUNTERS (void)m_compose_count; (void)m_flush_count; @@ -172,17 +173,13 @@ WSWindowManager::WSWindowManager() m_cursor_bitmap_inner = CharacterBitmap::create_from_ascii(cursor_bitmap_inner_ascii, 12, 17); m_cursor_bitmap_outer = CharacterBitmap::create_from_ascii(cursor_bitmap_outer_ascii, 12, 17); - { - LOCKER(m_wallpaper_path.lock()); - m_wallpaper_path.resource() = "/res/wallpapers/cool.rgb"; - m_wallpaper = GraphicsBitmap::load_from_file(m_wallpaper_path.resource(), m_screen_rect.size()); - } + m_wallpaper_path = "/res/wallpapers/cool.rgb"; + m_wallpaper = GraphicsBitmap::load_from_file(m_wallpaper_path, m_screen_rect.size()); #ifdef KERNEL ProcFS::the().add_sys_bool("wm_flash_flush", m_flash_flush); ProcFS::the().add_sys_string("wm_wallpaper", m_wallpaper_path, [this] { - LOCKER(m_wallpaper_path.lock()); - m_wallpaper = GraphicsBitmap::load_from_file(m_wallpaper_path.resource(), m_screen_rect.size()); + m_wallpaper = GraphicsBitmap::load_from_file(m_wallpaper_path, m_screen_rect.size()); invalidate(m_screen_rect); }); #endif @@ -201,25 +198,31 @@ WSWindowManager::WSWindowManager() m_system_menu->add_item(make<WSMenuItem>(4, "About...")); m_system_menu->on_item_activation = [] (WSMenuItem& item) { if (item.identifier() == 0) { - int error; - Process::create_user_process("/bin/Terminal", 100, 100, 0, error); + if (fork() == 0) { + execl("/bin/Terminal", "/bin/Terminal", nullptr); + ASSERT_NOT_REACHED(); + } return; } if (item.identifier() == 4) { - int error; - Process::create_user_process("/bin/About", 100, 100, 0, error); + if (fork() == 0) { + execl("/bin/About", "/bin/About", nullptr); + ASSERT_NOT_REACHED(); + } return; } - kprintf("WSMenu 1 item activated: '%s'\n", item.text().characters()); + dbgprintf("WSMenu 1 item activated: '%s'\n", item.text().characters()); }; } // NOTE: This ensures that the system menu has the correct dimensions. set_current_menubar(nullptr); +#if 0 WSMessageLoop::the().start_timer(300, [this] { invalidate(menubar_rect()); }); +#endif invalidate(); compose(); @@ -244,7 +247,6 @@ int WSWindowManager::menubar_menu_margin() const void WSWindowManager::set_current_menubar(WSMenuBar* menubar) { - LOCKER(m_lock); if (menubar) m_current_menubar = menubar->make_weak_ptr(); else @@ -279,7 +281,6 @@ static const int s_close_button_bitmap_height = 9; void WSWindowManager::paint_window_frame(WSWindow& window) { - LOCKER(m_lock); //printf("[WM] paint_window_frame {%p}, rect: %d,%d %dx%d\n", &window, window.rect().x(), window.rect().y(), window.rect().width(), window.rect().height()); if (window.type() == WSWindowType::Menu) { @@ -357,7 +358,6 @@ void WSWindowManager::paint_window_frame(WSWindow& window) void WSWindowManager::add_window(WSWindow& window) { - LOCKER(m_lock); m_windows.set(&window); m_windows_in_order.append(&window); if (!active_window()) @@ -366,7 +366,6 @@ void WSWindowManager::add_window(WSWindow& window) void WSWindowManager::move_to_front(WSWindow& window) { - LOCKER(m_lock); if (m_windows_in_order.tail() != &window) invalidate(window); m_windows_in_order.remove(&window); @@ -375,7 +374,6 @@ void WSWindowManager::move_to_front(WSWindow& window) void WSWindowManager::remove_window(WSWindow& window) { - LOCKER(m_lock); if (!m_windows.contains(&window)) return; @@ -395,7 +393,6 @@ void WSWindowManager::notify_title_changed(WSWindow& window) void WSWindowManager::notify_rect_changed(WSWindow& window, const Rect& old_rect, const Rect& new_rect) { printf("[WM] WSWindow %p rect changed (%d,%d %dx%d) -> (%d,%d %dx%d)\n", &window, old_rect.x(), old_rect.y(), old_rect.width(), old_rect.height(), new_rect.x(), new_rect.y(), new_rect.width(), new_rect.height()); - ASSERT_INTERRUPTS_ENABLED(); invalidate(outer_window_rect(old_rect)); invalidate(outer_window_rect(new_rect)); } @@ -469,7 +466,6 @@ void WSWindowManager::handle_close_button_mouse_event(WSWindow& window, WSMouseE void WSWindowManager::process_mouse_event(WSMouseEvent& event) { - LOCKER(m_lock); if (event.type() == WSMessage::MouseUp && event.button() == MouseButton::Left) { if (m_drag_window) { #ifdef DRAG_DEBUG @@ -597,14 +593,12 @@ IterationDecision WSWindowManager::for_each_visible_window_from_front_to_back(Ca void WSWindowManager::compose() { - LOCKER(m_lock); auto dirty_rects = move(m_dirty_rects); auto cursor_location = m_screen.cursor_location(); dirty_rects.append(m_last_cursor_rect); dirty_rects.append({ cursor_location.x(), cursor_location.y(), (int)m_cursor_bitmap_inner->width(), (int)m_cursor_bitmap_inner->height() }); #ifdef DEBUG_COUNTERS dbgprintf("[WM] compose #%u (%u rects)\n", ++m_compose_count, dirty_rects.size()); - dbgprintf("kmalloc stats: alloc:%u free:%u eternal:%u\n", sum_alloc, sum_free, kmalloc_sum_eternal); #endif auto any_window_contains_rect = [this] (const Rect& r) { @@ -630,7 +624,6 @@ void WSWindowManager::compose() if (any_window_contains_rect(dirty_rect)) { continue; } - LOCKER(m_wallpaper_path.lock()); if (!m_wallpaper) m_back_painter->fill_rect(dirty_rect, m_background_color); else @@ -663,7 +656,7 @@ void WSWindowManager::compose() draw_menubar(); draw_cursor(); - if (m_flash_flush.lock_and_copy()) { + if (m_flash_flush) { for (auto& rect : dirty_rects) m_front_painter->fill_rect(rect, Color::Yellow); } @@ -675,7 +668,6 @@ void WSWindowManager::compose() void WSWindowManager::invalidate_cursor() { - LOCKER(m_lock); auto cursor_location = m_screen.cursor_location(); Rect cursor_rect { cursor_location.x(), cursor_location.y(), (int)m_cursor_bitmap_inner->width(), (int)m_cursor_bitmap_inner->height() }; invalidate(cursor_rect); @@ -711,8 +703,6 @@ void WSWindowManager::draw_menubar() void WSWindowManager::draw_cursor() { - ASSERT_INTERRUPTS_ENABLED(); - LOCKER(m_lock); auto cursor_location = m_screen.cursor_location(); Rect cursor_rect { cursor_location.x(), cursor_location.y(), (int)m_cursor_bitmap_inner->width(), (int)m_cursor_bitmap_inner->height() }; Color inner_color = Color::White; @@ -726,8 +716,6 @@ void WSWindowManager::draw_cursor() void WSWindowManager::on_message(WSMessage& message) { - ASSERT_INTERRUPTS_ENABLED(); - LOCKER(m_lock); if (message.is_mouse_event()) return process_mouse_event(static_cast<WSMouseEvent&>(message)); @@ -747,7 +735,6 @@ void WSWindowManager::on_message(WSMessage& message) void WSWindowManager::set_active_window(WSWindow* window) { - LOCKER(m_lock); if (window->type() == WSWindowType::Menu) { dbgprintf("WSWindowManager: Attempted to make a menu window active.\n"); return; @@ -777,14 +764,12 @@ void WSWindowManager::set_active_window(WSWindow* window) void WSWindowManager::invalidate() { - LOCKER(m_lock); m_dirty_rects.clear_with_capacity(); invalidate(m_screen_rect); } void WSWindowManager::invalidate(const Rect& a_rect) { - LOCKER(m_lock); auto rect = Rect::intersection(a_rect, m_screen_rect); if (rect.is_empty()) return; @@ -803,7 +788,6 @@ void WSWindowManager::invalidate(const Rect& a_rect) m_dirty_rects.append(rect); if (!m_pending_compose_event) { - ASSERT_INTERRUPTS_ENABLED(); WSMessageLoop::the().post_message(this, make<WSMessage>(WSMessage::WM_DeferredCompose)); m_pending_compose_event = true; } @@ -811,8 +795,6 @@ void WSWindowManager::invalidate(const Rect& a_rect) void WSWindowManager::invalidate(const WSWindow& window) { - ASSERT_INTERRUPTS_ENABLED(); - LOCKER(m_lock); invalidate(outer_window_rect(window.rect())); } @@ -822,8 +804,6 @@ void WSWindowManager::invalidate(const WSWindow& window, const Rect& rect) invalidate(window); return; } - ASSERT_INTERRUPTS_ENABLED(); - LOCKER(m_lock); auto outer_rect = outer_window_rect(window.rect()); auto inner_rect = rect; inner_rect.move_by(window.position()); @@ -853,14 +833,12 @@ void WSWindowManager::flush(const Rect& a_rect) void WSWindowManager::close_menu(WSMenu& menu) { - LOCKER(m_lock); if (current_menu() == &menu) close_current_menu(); } void WSWindowManager::close_menubar(WSMenuBar& menubar) { - LOCKER(m_lock); if (current_menubar() == &menubar) set_current_menubar(nullptr); } diff --git a/WindowServer/WSWindowManager.h b/WindowServer/WSWindowManager.h index 2c97e09853..08631f3b92 100644 --- a/WindowServer/WSWindowManager.h +++ b/WindowServer/WSWindowManager.h @@ -6,7 +6,6 @@ #include <AK/HashTable.h> #include <AK/InlineLinkedList.h> #include <AK/WeakPtr.h> -#include <AK/Lock.h> #include <AK/HashMap.h> #include "WSMessageReceiver.h" #include "WSMenuBar.h" @@ -27,6 +26,10 @@ enum class IterationDecision { Continue, Abort }; class WSWindowManager : public WSMessageReceiver { public: static WSWindowManager& the(); + + WSWindowManager(); + virtual ~WSWindowManager() override; + void add_window(WSWindow&); void remove_window(WSWindow&); @@ -67,9 +70,6 @@ public: void set_framebuffer_fd(int fd) { m_framebuffer_fd = fd; } private: - WSWindowManager(); - virtual ~WSWindowManager() override; - void process_mouse_event(WSMouseEvent&); void handle_menu_mouse_event(WSMenu&, WSMouseEvent&); void handle_menubar_mouse_event(WSMouseEvent&); @@ -139,12 +139,10 @@ private: RetainPtr<Font> m_font; - Lockable<String> m_wallpaper_path; + String m_wallpaper_path; RetainPtr<GraphicsBitmap> m_wallpaper; - mutable Lock m_lock; - - Lockable<bool> m_flash_flush; + bool m_flash_flush { false }; bool m_buffers_are_flipped { false }; OwnPtr<WSMenu> m_system_menu; diff --git a/WindowServer/main.cpp b/WindowServer/main.cpp index 9454b9793f..f74ad07f76 100644 --- a/WindowServer/main.cpp +++ b/WindowServer/main.cpp @@ -1,19 +1,19 @@ -#include "Process.h" #include <SharedGraphics/Font.h> #include <WindowServer/WSScreen.h> #include <WindowServer/WSWindowManager.h> #include <WindowServer/WSMessageLoop.h> #include <WindowServer/WSWindow.h> +#include <unistd.h> +#include <fcntl.h> +#include <sys/ioctl.h> +#include <sys/mman.h> -// NOTE: This actually runs as a kernel process. -// I'd like to change this eventually. - -void WindowServer_main() +int main(int, char**) { - WSMessageLoop::the().set_server_process(*current); - current->set_priority(Process::HighPriority); + dbgprintf("WindowServer starting...\n"); + WSMessageLoop loop; - int bxvga_fd = current->sys$open("/dev/bxvga", O_RDWR); + int bxvga_fd = open("/dev/bxvga", O_RDWR); ASSERT(bxvga_fd >= 0); struct BXVGAResolution { @@ -21,24 +21,17 @@ void WindowServer_main() int height; }; BXVGAResolution resolution { 1024, 768 }; - - int rc = current->sys$ioctl(bxvga_fd, 1985, (int)&resolution); + int rc = ioctl(bxvga_fd, 1985, (int)&resolution); ASSERT(rc == 0); - Syscall::SC_mmap_params params; - memset(¶ms, 0, sizeof(params)); - params.fd = bxvga_fd; - params.prot = PROT_READ | PROT_WRITE; - params.flags = MAP_SHARED; - params.size = resolution.width * resolution.height * sizeof(RGBA32) * 2; - params.offset = 0; - kprintf("Calling sys$mmap in WS\n"); - void* framebuffer = current->sys$mmap(¶ms); + size_t framebuffer_size_in_bytes = resolution.width * resolution.height * sizeof(RGBA32) * 2; + void* framebuffer = mmap(nullptr, framebuffer_size_in_bytes, PROT_READ | PROT_WRITE, MAP_SHARED, bxvga_fd, 0); ASSERT(framebuffer && framebuffer != (void*)-1); WSScreen screen((dword*)framebuffer, resolution.width, resolution.height); - WSWindowManager::the().set_framebuffer_fd(bxvga_fd); + WSWindowManager window_manager; + window_manager.set_framebuffer_fd(bxvga_fd); dbgprintf("Entering WindowServer main loop.\n"); WSMessageLoop::the().exec(); |