summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Kling <awesomekling@gmail.com>2019-02-17 00:13:47 +0100
committerAndreas Kling <awesomekling@gmail.com>2019-02-17 00:13:47 +0100
commit640360e958d6dea05ba0e294af52160bc10725cb (patch)
tree509ac7609062108169b8332064ebfae40edef1c6
parent0b1b21d62286b73b8c59a2ce12e75a6de0f84f13 (diff)
downloadserenity-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 :^)
-rw-r--r--Kernel/BochsVGADevice.cpp4
-rw-r--r--Kernel/FileDescriptor.cpp6
-rw-r--r--Kernel/KeyCode.h17
-rw-r--r--Kernel/Keyboard.h17
-rw-r--r--Kernel/LocalSocket.cpp35
-rw-r--r--Kernel/LocalSocket.h4
-rw-r--r--Kernel/Makefile24
-rw-r--r--Kernel/MemoryManager.cpp7
-rw-r--r--Kernel/MemoryManager.h1
-rw-r--r--Kernel/Process.cpp41
-rw-r--r--Kernel/Process.h3
-rw-r--r--Kernel/Socket.h2
-rw-r--r--Kernel/init.cpp11
-rwxr-xr-xKernel/makeall.sh2
-rwxr-xr-xKernel/sync.sh1
-rw-r--r--LibC/Makefile2
-rw-r--r--LibC/errno_numbers.h1
-rw-r--r--LibC/unistd.cpp6
-rw-r--r--LibGUI/GEventLoop.cpp3
-rw-r--r--LibGUI/GWidget.cpp4
-rw-r--r--SharedGraphics/Font.cpp40
-rw-r--r--SharedGraphics/Font.h3
-rw-r--r--SharedGraphics/GraphicsBitmap.cpp57
-rw-r--r--SharedGraphics/GraphicsBitmap.h13
-rw-r--r--SharedGraphics/Painter.cpp13
-rw-r--r--SharedGraphics/Painter.h7
-rw-r--r--WindowServer/.gitignore1
-rw-r--r--WindowServer/Makefile52
-rw-r--r--WindowServer/WSAPITypes.h6
-rw-r--r--WindowServer/WSClientConnection.cpp64
-rw-r--r--WindowServer/WSClientConnection.h4
-rw-r--r--WindowServer/WSMessage.h15
-rw-r--r--WindowServer/WSMessageLoop.cpp188
-rw-r--r--WindowServer/WSMessageLoop.h11
-rw-r--r--WindowServer/WSMessageReceiver.cpp1
-rw-r--r--WindowServer/WSScreen.cpp3
-rw-r--r--WindowServer/WSScreen.h4
-rw-r--r--WindowServer/WSWindow.cpp2
-rw-r--r--WindowServer/WSWindowManager.cpp66
-rw-r--r--WindowServer/WSWindowManager.h14
-rw-r--r--WindowServer/main.cpp33
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(&params, 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(&params);
+ 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(&params);
- 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(&params, 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(&params);
+ 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();