Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
20bf0fc
began developing the stellux display manager and userland graphics li…
FlareCoding Jun 22, 2025
5475fe5
made huge progress on the display manager and implemented kernel supp…
FlareCoding Jun 23, 2025
b219763
added framebuffer_op syscall operations to toggle preemption settings…
FlareCoding Jun 23, 2025
525cf6d
implemented stlibc extensions for the Stellux kernel shared memory API
FlareCoding Jun 23, 2025
15c2a36
added the ability to set sockets to be non-blocking
FlareCoding Jun 24, 2025
94a3dd4
first functioning double-buffered DM + app communication mechanism
FlareCoding Jun 24, 2025
3f2fadd
functioning implementation of UI rendering using triple-buffering
FlareCoding Jun 24, 2025
38ee966
removed debug messages and implemented font loading in userland apps
FlareCoding Jun 24, 2025
320f4ec
integrated access to the input subsystem into the stellux display man…
FlareCoding Jun 24, 2025
4db0de4
added support for the clock_gettime syscall
FlareCoding Jun 24, 2025
16575e9
fixed an insane critical bug in the xhci handler calling yield() thro…
FlareCoding Jun 25, 2025
5e4deb7
improved event routing and accountance for window client area vs titl…
FlareCoding Jun 25, 2025
b33b059
fixed pressed vs clicked event differentiation when dealing with wind…
FlareCoding Jun 25, 2025
fcfaf43
implemented window dragging
FlareCoding Jun 26, 2025
e03aaa8
example terminal application with event routing
FlareCoding Jun 26, 2025
25b2f4c
implemented window closing functionality
FlareCoding Jun 26, 2025
5878040
fixed the way modifier keys are handled
FlareCoding Jun 26, 2025
4fec6f9
replaced the shell with a 'stlxterm' terminal emulator
FlareCoding Jun 26, 2025
04a6a92
fixed event type definitions and added a splash screen to the display…
FlareCoding Jun 26, 2025
799e4bc
added a typing animation for the username on the splash screen
FlareCoding Jun 26, 2025
611792a
added builtin commands to the stlxterm emulator
FlareCoding Jun 26, 2025
338d589
improved the terminal size
FlareCoding Jun 26, 2025
fb7ac6f
added a HUD menu bar to the display manager
FlareCoding Jun 27, 2025
4fde082
removed old unused flags from the grub config
FlareCoding Jun 27, 2025
89bf9c1
added limited support for the reboot syscall
FlareCoding Jun 27, 2025
010afdf
added the ability to start multiple terminal windows through shortcuts
FlareCoding Jun 27, 2025
a97316d
removed redundant verbose print statements
FlareCoding Jun 27, 2025
944549a
removed clock hud component click traces
FlareCoding Jun 27, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion grub/grub.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ else
fi

menuentry "Stellux 2.0" {
multiboot2 /boot/stellux -- "debug=true use-pci-serial=true gfxmode=compositor"
multiboot2 /boot/stellux -- "debug=true use-pci-serial=true"
module2 /boot/initrd "initrd"
boot
}
1 change: 1 addition & 0 deletions kernel/include/drivers/usb/xhci/xhci.h
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,7 @@ class xhci_driver : public pci_device_driver {
kstl::vector<xhci_port_status_change_trb_t*> m_port_status_change_events;
kstl::vector<xhci_command_completion_trb_t*> m_command_completion_events;
kstl::vector<xhci_transfer_completion_trb_t*> m_transfer_completion_events;
kstl::vector<xhci_trb_t*> m_events_buffer; // Preallocated buffer for IRQ events

volatile uint8_t m_command_irq_completed = 0;
volatile uint8_t m_transfer_irq_completed = 0;
Expand Down
6 changes: 6 additions & 0 deletions kernel/include/drivers/usb/xhci/xhci_usb_hid_mouse_driver.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,20 @@ class xhci_usb_hid_mouse_driver : public xhci_usb_hid_driver {
uint16_t x_axis_size;
uint16_t y_axis_offset;
uint16_t y_axis_size;
uint16_t scroll_offset;
uint16_t scroll_size;
} m_input_layout;

uint32_t m_previous_button_state; // Track previous button state for press/release detection

void _initialize_input_field(
hid::hid_report_layout& layout,
uint16_t usage_page, uint16_t usage,
uint16_t& offset, uint16_t& size,
const char* field_name
);

void _emit_input_event(uint32_t event_type, uint32_t udata1, uint32_t udata2, int32_t sdata1, int32_t sdata2);
};

#endif // XHCI_USB_HID_MOUSE_DRIVER_H
75 changes: 73 additions & 2 deletions kernel/include/input/input_event.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@
#define INPUT_EVENT_H
#include <types.h>

#define INPUT_QUEUE_ID_KBD 0x0001
#define INPUT_QUEUE_ID_POINTER 0x0002
#define INPUT_QUEUE_ID_SYSTEM 0x0001 // Handles both, kbd and pointer events

namespace input {
enum input_event_type : uint32_t {
Expand All @@ -26,6 +25,78 @@ struct input_event_t {
int32_t sdata1; // Event-specific signed data 1
int32_t sdata2; // Event-specific signed data 2
} __attribute__((packed));

/**
* @brief Keyboard key pressed event structure.
*/
struct keyboard_key_pressed_event_t {
uint32_t id; // Event-specific ID
input_event_type type; // Always KBD_EVT_KEY_PRESSED
uint32_t keycode; // Key code of the pressed key
uint32_t modifiers; // Modifier keys state (Ctrl, Alt, Shift, etc.)
int32_t ascii_char; // ASCII character representation
int32_t reserved; // Reserved for future use
} __attribute__((packed));

/**
* @brief Keyboard key released event structure.
*/
struct keyboard_key_released_event_t {
uint32_t id; // Event-specific ID
input_event_type type; // Always KBD_EVT_KEY_RELEASED
uint32_t keycode; // Key code of the released key
uint32_t modifiers; // Modifier keys state (Ctrl, Alt, Shift, etc.)
int32_t reserved1; // Reserved for future use
int32_t reserved2; // Reserved for future use
} __attribute__((packed));

/**
* @brief Mouse movement event structure.
*/
struct pointer_mouse_moved_event_t {
uint32_t id; // Event-specific ID
input_event_type type; // Always POINTER_EVT_MOUSE_MOVED
uint32_t x_pos; // Current X position of mouse cursor
uint32_t y_pos; // Current Y position of mouse cursor
int32_t delta_x; // Change in X position since last event
int32_t delta_y; // Change in Y position since last event
} __attribute__((packed));

/**
* @brief Mouse button pressed event structure.
*/
struct pointer_mouse_btn_pressed_event_t {
uint32_t id; // Event-specific ID
input_event_type type; // Always POINTER_EVT_MOUSE_BTN_PRESSED
uint32_t button; // Button that was pressed (1=left, 2=right, 3=middle, etc.)
uint32_t x_pos; // X position when button was pressed
int32_t y_pos; // Y position when button was pressed
int32_t reserved; // Reserved for future use
} __attribute__((packed));

/**
* @brief Mouse button released event structure.
*/
struct pointer_mouse_btn_released_event_t {
uint32_t id; // Event-specific ID
input_event_type type; // Always POINTER_EVT_MOUSE_BTN_RELEASED
uint32_t button; // Button that was released (1=left, 2=right, 3=middle, etc.)
uint32_t x_pos; // X position when button was released
int32_t y_pos; // Y position when button was released
int32_t reserved; // Reserved for future use
} __attribute__((packed));

/**
* @brief Mouse scroll event structure.
*/
struct pointer_mouse_scrolled_event_t {
uint32_t id; // Event-specific ID
input_event_type type; // Always POINTER_EVT_MOUSE_SCROLLED
uint32_t scroll_type; // Type of scroll (0=vertical, 1=horizontal)
uint32_t x_pos; // X position when scroll occurred
int32_t y_pos; // Y position when scroll occurred
int32_t scroll_delta; // Scroll amount (positive=up/right, negative=down/left)
} __attribute__((packed));
} // namespace input

#endif // INPUT_EVENT_H
Expand Down
6 changes: 6 additions & 0 deletions kernel/include/input/system_input_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,12 @@ class system_input_manager {
*/
bool push_event(uint32_t queue_id, const input_event_t& event);

/**
* @brief Gets the system input queue (ID: INPUT_QUEUE_ID_SYSTEM).
* @return Pointer to the system input queue, or nullptr if not found.
*/
input_queue* get_system_input_queue();

private:
kstl::hashmap<uint32_t, input_queue*> m_input_queues; // Stores input queues mapped by ID.
};
Expand Down
14 changes: 11 additions & 3 deletions kernel/include/ipc/shm.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,15 @@ using shm_handle_t = uint64_t;
enum class shm_access {
READ_ONLY, // Region is read-only.
READ_WRITE, // Region is readable and writable.
COPY_ON_WRITE // Region starts read-only, create private copy on write.
};

/**
* @enum shm_mapping_context
* @brief Describes the context in which shared memory is being mapped.
*/
enum class shm_mapping_context {
KERNEL, // Kernel thread mapping - use vmm directly
USERLAND // Userland process mapping - use VMA system
};

/**
Expand Down Expand Up @@ -50,10 +58,10 @@ class shared_memory {
static bool destroy(shm_handle_t handle);

/** Map a shared memory region into the caller address space. */
static void* map(shm_handle_t handle, uint64_t flags);
static void* map(shm_handle_t handle, uint64_t flags, shm_mapping_context context);

/** Unmap a previously mapped shared memory region. */
static bool unmap(shm_handle_t handle, void* addr);
static bool unmap(shm_handle_t handle, void* addr, shm_mapping_context context);

private:
static shm_region* get_region(shm_handle_t handle);
Expand Down
205 changes: 205 additions & 0 deletions kernel/include/net/unix_socket.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,205 @@
#ifndef UNIX_SOCKET_H
#define UNIX_SOCKET_H

#include <core/sync.h>
#include <core/types.h>
#include <core/string.h>
#include <kstl/vector.h>
#include <memory/memory.h>
#include <net/unix_socket_buffer.h>

// Uncomment the line below to enable verbose Unix socket debugging
// #define STELLUX_UNIX_SOCKET_DEBUG

#ifdef STELLUX_UNIX_SOCKET_DEBUG
#include <core/klog.h>
#define UNIX_SOCKET_TRACE(...) kprint(__VA_ARGS__)
#else
#define UNIX_SOCKET_TRACE(...) do { } while(0)
#endif

namespace net {

/**
* @enum unix_socket_state
* @brief Represents the state of a Unix socket.
*/
enum class unix_socket_state : uint32_t {
INVALID = 0, // Socket is invalid/uninitialized
CREATED, // Socket created but not bound/connected
BOUND, // Server socket bound to path
LISTENING, // Server socket listening for connections
CONNECTING, // Client socket attempting to connect
CONNECTED, // Connected socket (client or accepted connection)
DISCONNECTED, // Socket disconnected but not closed
CLOSED // Socket closed and resources freed
};

/**
* @class unix_stream_socket
* @brief Unix domain stream socket implementation.
*
* Provides reliable, ordered, connection-based communication between processes
* on the same machine using filesystem paths as addresses.
*/
class unix_stream_socket {
public:
/**
* @brief Constructs a new Unix stream socket.
*/
unix_stream_socket();

/**
* @brief Destructor - cleans up socket resources.
*/
~unix_stream_socket();

// Non-copyable, non-movable for thread safety
unix_stream_socket(const unix_stream_socket&) = delete;
unix_stream_socket& operator=(const unix_stream_socket&) = delete;
unix_stream_socket(unix_stream_socket&&) = delete;
unix_stream_socket& operator=(unix_stream_socket&&) = delete;

/**
* @brief Binds the socket to a filesystem path.
*
* Creates a socket file at the specified path that clients can connect to.
* Only server sockets need to bind to a path.
*
* @param path Filesystem path to bind to (e.g., "/tmp/my_socket")
* @return 0 on success, negative error code on failure
*/
int bind(const kstl::string& path);

/**
* @brief Puts the socket into listening mode.
*
* Marks the socket as passive, ready to accept incoming connections.
* Must be called after bind() and before accept().
*
* @param backlog Maximum number of pending connections (default: 5)
* @return 0 on success, negative error code on failure
*/
int listen(int backlog = 5);

/**
* @brief Accepts an incoming connection (blocking).
*
* Blocks until a client connects, then returns a new socket for that connection.
* The original socket remains in listening state for more connections.
*
* @return Shared pointer to new socket for the connection, or nullptr on error
*/
kstl::shared_ptr<unix_stream_socket> accept();

/**
* @brief Connects to a server socket (blocking).
*
* Attempts to establish a connection to a server socket at the given path.
* Blocks until connection is established or fails.
*
* @param path Path to connect to
* @return 0 on success, negative error code on failure
*/
int connect(const kstl::string& path);

/**
* @brief Reads data from the socket (blocking).
*
* Blocks until data is available or the connection is closed.
* For stream sockets, may return fewer bytes than requested.
*
* @param buffer Buffer to read data into
* @param size Maximum number of bytes to read
* @return Number of bytes read, 0 for EOF, negative for error
*/
ssize_t read(void* buffer, size_t size);

/**
* @brief Writes data to the socket.
*
* Attempts to write data to the connected peer. May write fewer bytes
* than requested if the peer's receive buffer is full.
*
* @param data Data to write
* @param size Number of bytes to write
* @return Number of bytes written, negative for error
*/
ssize_t write(const void* data, size_t size);

/**
* @brief Closes the socket.
*
* Closes the socket and releases all associated resources.
* Any pending operations will be interrupted.
*
* @return 0 on success, negative error code on failure
*/
int close();

/**
* @brief Registers this socket with the manager (for server sockets).
*
* Must be called after bind() for server sockets to make them discoverable.
* This is a separate step to avoid shared_ptr issues in bind().
*
* @param self Shared pointer to this socket instance
* @return 0 on success, negative error code on failure
*/
int register_with_manager(kstl::shared_ptr<unix_stream_socket> self);

// State and property getters
unix_socket_state get_state() const { return m_state.load(); }
const kstl::string& get_path() const { return m_path; }
bool is_server() const { return m_is_server; }
bool is_connected() const { return get_state() == unix_socket_state::CONNECTED; }
bool is_listening() const { return get_state() == unix_socket_state::LISTENING; }
bool is_nonblocking() const { return m_nonblocking; }

/**
* @brief Sets the socket to blocking or non-blocking mode.
*
* @param nonblocking True for non-blocking, false for blocking
* @return 0 on success, negative error code on failure
*/
int set_nonblocking(bool nonblocking);

private:
// Core socket state
atomic<unix_socket_state> m_state = atomic<unix_socket_state>(unix_socket_state::CREATED);
kstl::string m_path; // Bound path (for server sockets)
bool m_is_server = false; // True if this is a server socket
bool m_nonblocking = false; // True if socket is in non-blocking mode
int m_backlog = 0; // Listen backlog size

// Connection management
kstl::shared_ptr<unix_stream_socket> m_peer; // Connected peer socket
kstl::vector<kstl::shared_ptr<unix_stream_socket>> m_pending_connections; // Pending accept queue

// Data buffers
kstl::shared_ptr<unix_socket_buffer> m_recv_buffer; // Incoming data buffer
kstl::shared_ptr<unix_socket_buffer> m_send_buffer; // Outgoing data buffer

// Synchronization
mutable mutex m_socket_lock = mutex(); // Protects socket state
mutex m_accept_lock = mutex(); // Protects pending connections

// Private helper methods
void _change_state(unix_socket_state new_state);
bool _can_accept() const;
bool _can_read() const;
bool _can_write() const;
void _cleanup_resources();
void _setup_buffers();
int _add_pending_connection(kstl::shared_ptr<unix_stream_socket> client);
kstl::shared_ptr<unix_stream_socket> _get_pending_connection();
void _set_peer(kstl::shared_ptr<unix_stream_socket> peer);

// Allow manager to access private members for connection setup
friend class unix_socket_manager;
};

} // namespace net

#endif // UNIX_SOCKET_H

Loading