mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 05:27:45 +00:00
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 :^)
This commit is contained in:
parent
0b1b21d622
commit
640360e958
41 changed files with 325 additions and 463 deletions
1
WindowServer/.gitignore
vendored
1
WindowServer/.gitignore
vendored
|
@ -1,2 +1,3 @@
|
|||
*.o
|
||||
*.d
|
||||
WindowServer
|
||||
|
|
52
WindowServer/Makefile
Normal file
52
WindowServer/Makefile
Normal file
|
@ -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
|
||||
|
|
@ -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;
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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&);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 };
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
#include "WSMessageReceiver.h"
|
||||
#include <AK/Assertions.h>
|
||||
|
||||
WSMessageReceiver::WSMessageReceiver()
|
||||
{
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue