Compare commits
No commits in common. "5c96a31cd8a969f38795be22e09bfe8a1e4979af" and "b01aa72f176cde5f28e56f456e6efb01a7c9de8a" have entirely different histories.
5c96a31cd8
...
b01aa72f17
@ -45,10 +45,8 @@ endif()
|
|||||||
|
|
||||||
add_subdirectory(libluna)
|
add_subdirectory(libluna)
|
||||||
add_subdirectory(libos)
|
add_subdirectory(libos)
|
||||||
add_subdirectory(libui)
|
|
||||||
add_subdirectory(libc)
|
add_subdirectory(libc)
|
||||||
add_subdirectory(kernel)
|
add_subdirectory(kernel)
|
||||||
add_subdirectory(apps)
|
add_subdirectory(apps)
|
||||||
add_subdirectory(tests)
|
add_subdirectory(tests)
|
||||||
add_subdirectory(shell)
|
add_subdirectory(shell)
|
||||||
add_subdirectory(wind)
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
Name=login
|
Name=login
|
||||||
Description=Start the display server.
|
Description=Start the command-line login program.
|
||||||
Command=/usr/bin/wind --user=selene
|
Command=/usr/bin/login
|
||||||
Restart=true
|
Restart=true
|
||||||
|
@ -43,8 +43,8 @@ static void process_mouse_event(u8 data)
|
|||||||
packet.buttons = 0;
|
packet.buttons = 0;
|
||||||
|
|
||||||
u8 flags = g_mouse_packet[0];
|
u8 flags = g_mouse_packet[0];
|
||||||
if (flags & PS2_MOUSE_X_SIGN) packet.xdelta = -(256 - packet.xdelta);
|
if (flags & PS2_MOUSE_X_SIGN) packet.xdelta = -packet.xdelta;
|
||||||
if (flags & PS2_MOUSE_Y_SIGN) packet.ydelta = -(256 - packet.ydelta);
|
if (flags & PS2_MOUSE_Y_SIGN) packet.ydelta = -packet.ydelta;
|
||||||
|
|
||||||
if (flags & PS2_MOUSE_MIDDLE_BTN) packet.buttons |= moon::MouseButton::Middle;
|
if (flags & PS2_MOUSE_MIDDLE_BTN) packet.buttons |= moon::MouseButton::Middle;
|
||||||
if (flags & PS2_MOUSE_RIGHT_BTN) packet.buttons |= moon::MouseButton::Right;
|
if (flags & PS2_MOUSE_RIGHT_BTN) packet.buttons |= moon::MouseButton::Right;
|
||||||
|
@ -1,15 +0,0 @@
|
|||||||
# The UI and graphics library for Luna.
|
|
||||||
|
|
||||||
file(GLOB HEADERS include/ui/*.h)
|
|
||||||
|
|
||||||
set(SOURCES
|
|
||||||
${HEADERS}
|
|
||||||
src/Canvas.cpp
|
|
||||||
src/Color.cpp
|
|
||||||
src/Rect.cpp
|
|
||||||
)
|
|
||||||
|
|
||||||
add_library(ui ${SOURCES})
|
|
||||||
target_compile_options(ui PRIVATE ${COMMON_FLAGS})
|
|
||||||
target_include_directories(ui PUBLIC ${CMAKE_CURRENT_LIST_DIR}/include/)
|
|
||||||
target_include_directories(ui PUBLIC ${LUNA_BASE}/usr/include)
|
|
@ -1,30 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include <luna/Result.h>
|
|
||||||
#include <luna/Types.h>
|
|
||||||
#include <ui/Color.h>
|
|
||||||
#include <ui/Point.h>
|
|
||||||
#include <ui/Rect.h>
|
|
||||||
|
|
||||||
namespace ui
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* @brief A drawable surface.
|
|
||||||
*/
|
|
||||||
struct Canvas
|
|
||||||
{
|
|
||||||
int width;
|
|
||||||
int height;
|
|
||||||
int stride;
|
|
||||||
u8* ptr;
|
|
||||||
|
|
||||||
static Canvas create(u8* ptr, int width, int height);
|
|
||||||
Result<Canvas> subcanvas(Point begin, int width, int height, bool clamp);
|
|
||||||
|
|
||||||
Rect rect()
|
|
||||||
{
|
|
||||||
return Rect { .begin = { 0, 0 }, .width = width, .height = height };
|
|
||||||
}
|
|
||||||
|
|
||||||
void fill(Color color);
|
|
||||||
};
|
|
||||||
};
|
|
@ -1,34 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include <luna/Types.h>
|
|
||||||
|
|
||||||
namespace ui
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* @brief A 32-bit RGBA color.
|
|
||||||
*/
|
|
||||||
struct Color
|
|
||||||
{
|
|
||||||
union {
|
|
||||||
u32 raw;
|
|
||||||
u8 colors[4];
|
|
||||||
};
|
|
||||||
|
|
||||||
static constexpr Color from_u32(u32 raw)
|
|
||||||
{
|
|
||||||
return Color { .raw = raw };
|
|
||||||
}
|
|
||||||
|
|
||||||
static constexpr Color from_rgba(u8 red, u8 green, u8 blue, u8 alpha)
|
|
||||||
{
|
|
||||||
return Color { .colors = { blue, green, red, alpha } };
|
|
||||||
}
|
|
||||||
|
|
||||||
static constexpr Color from_rgb(u8 red, u8 green, u8 blue)
|
|
||||||
{
|
|
||||||
return from_rgba(red, green, blue, 0xff);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
static constexpr Color WHITE = Color::from_rgb(0xff, 0xff, 0xff);
|
|
||||||
static constexpr Color BLACK = Color::from_rgb(0x00, 0x00, 0x00);
|
|
||||||
};
|
|
@ -1,13 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
namespace ui
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* @brief A point in 2D space.
|
|
||||||
*/
|
|
||||||
struct Point
|
|
||||||
{
|
|
||||||
int x { 0 };
|
|
||||||
int y { 0 };
|
|
||||||
};
|
|
||||||
}
|
|
@ -1,18 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include <ui/Point.h>
|
|
||||||
|
|
||||||
namespace ui
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* @brief A simple rectangle.
|
|
||||||
*/
|
|
||||||
struct Rect
|
|
||||||
{
|
|
||||||
Point begin;
|
|
||||||
int width;
|
|
||||||
int height;
|
|
||||||
|
|
||||||
bool contains(Point point);
|
|
||||||
Point normalize(Point point);
|
|
||||||
};
|
|
||||||
}
|
|
@ -1,43 +0,0 @@
|
|||||||
#include <string.h>
|
|
||||||
#include <ui/Canvas.h>
|
|
||||||
|
|
||||||
namespace ui
|
|
||||||
{
|
|
||||||
Canvas Canvas::create(u8* ptr, int width, int height)
|
|
||||||
{
|
|
||||||
return Canvas { .width = width, .height = height, .stride = width, .ptr = ptr };
|
|
||||||
}
|
|
||||||
|
|
||||||
Result<Canvas> Canvas::subcanvas(Point begin, int w, int h, bool clamp)
|
|
||||||
{
|
|
||||||
if (!clamp)
|
|
||||||
{
|
|
||||||
if (begin.x + w > width) return err(ERANGE);
|
|
||||||
if (begin.y + h > height) return err(ERANGE);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (begin.x + w > width) w = width - begin.x;
|
|
||||||
if (begin.y + h > height) h = height - begin.y;
|
|
||||||
}
|
|
||||||
|
|
||||||
u8* p = ptr + begin.x * sizeof(Color) + (begin.y * sizeof(Color) * stride);
|
|
||||||
|
|
||||||
return Canvas { .width = w, .height = h, .stride = stride, .ptr = p };
|
|
||||||
}
|
|
||||||
|
|
||||||
void Canvas::fill(Color color)
|
|
||||||
{
|
|
||||||
u8* p = ptr;
|
|
||||||
for (int i = 0; i < height; i++)
|
|
||||||
{
|
|
||||||
u32* colorp = (u32*)p;
|
|
||||||
for (int j = 0; j < width; j++)
|
|
||||||
{
|
|
||||||
*colorp = color.raw;
|
|
||||||
colorp++;
|
|
||||||
}
|
|
||||||
p += stride * sizeof(Color);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,18 +0,0 @@
|
|||||||
#include <ui/Rect.h>
|
|
||||||
|
|
||||||
namespace ui
|
|
||||||
{
|
|
||||||
bool Rect::contains(Point point)
|
|
||||||
{
|
|
||||||
return point.x >= begin.x && point.y >= begin.y && point.x <= begin.x + width && point.y <= begin.y + height;
|
|
||||||
}
|
|
||||||
|
|
||||||
Point Rect::normalize(Point point)
|
|
||||||
{
|
|
||||||
if (point.x < begin.x) point.x = begin.x;
|
|
||||||
if (point.y < begin.y) point.y = begin.y;
|
|
||||||
if (point.x > begin.x + width) point.x = begin.x + width;
|
|
||||||
if (point.y > begin.y + height) point.y = begin.y + height;
|
|
||||||
return point;
|
|
||||||
}
|
|
||||||
};
|
|
@ -8,12 +8,10 @@ cd $LUNA_ROOT
|
|||||||
mkdir -p $LUNA_BASE
|
mkdir -p $LUNA_BASE
|
||||||
mkdir -p $LUNA_BASE/usr/include
|
mkdir -p $LUNA_BASE/usr/include
|
||||||
mkdir -p $LUNA_BASE/usr/include/luna
|
mkdir -p $LUNA_BASE/usr/include/luna
|
||||||
mkdir -p $LUNA_BASE/usr/include/ui
|
|
||||||
mkdir -p $LUNA_BASE/usr/include/os
|
mkdir -p $LUNA_BASE/usr/include/os
|
||||||
mkdir -p $LUNA_BASE/usr/include/moon
|
mkdir -p $LUNA_BASE/usr/include/moon
|
||||||
|
|
||||||
cp --preserve=timestamps -RT libc/include/ $LUNA_BASE/usr/include
|
cp --preserve=timestamps -RT libc/include/ $LUNA_BASE/usr/include
|
||||||
cp --preserve=timestamps -RT libluna/include/luna/ $LUNA_BASE/usr/include/luna
|
cp --preserve=timestamps -RT libluna/include/luna/ $LUNA_BASE/usr/include/luna
|
||||||
cp --preserve=timestamps -RT libui/include/ui/ $LUNA_BASE/usr/include/ui
|
|
||||||
cp --preserve=timestamps -RT libos/include/os/ $LUNA_BASE/usr/include/os
|
cp --preserve=timestamps -RT libos/include/os/ $LUNA_BASE/usr/include/os
|
||||||
cp --preserve=timestamps -RT kernel/src/api/ $LUNA_BASE/usr/include/moon
|
cp --preserve=timestamps -RT kernel/src/api/ $LUNA_BASE/usr/include/moon
|
||||||
|
@ -4,7 +4,7 @@ source $(dirname $0)/env.sh
|
|||||||
|
|
||||||
cd $LUNA_ROOT
|
cd $LUNA_ROOT
|
||||||
|
|
||||||
FOLDERS=(kernel libc libos libui libluna apps shell tests)
|
FOLDERS=(kernel libc libos libluna apps shell tests)
|
||||||
|
|
||||||
SOURCES=($(find ${FOLDERS[@]} -type f -name "*.cpp"))
|
SOURCES=($(find ${FOLDERS[@]} -type f -name "*.cpp"))
|
||||||
SOURCES+=($(find ${FOLDERS[@]} -type f -name "*.h"))
|
SOURCES+=($(find ${FOLDERS[@]} -type f -name "*.h"))
|
||||||
|
@ -1,14 +0,0 @@
|
|||||||
set(SOURCES
|
|
||||||
main.cpp
|
|
||||||
Screen.h
|
|
||||||
Screen.cpp
|
|
||||||
Mouse.h
|
|
||||||
Mouse.cpp
|
|
||||||
)
|
|
||||||
|
|
||||||
add_executable(wind ${SOURCES})
|
|
||||||
target_compile_options(wind PRIVATE -Os ${COMMON_FLAGS} -Wno-write-strings)
|
|
||||||
add_dependencies(wind libc)
|
|
||||||
target_include_directories(wind PRIVATE ${LUNA_BASE}/usr/include ${CMAKE_CURRENT_LIST_DIR})
|
|
||||||
target_link_libraries(wind PRIVATE os ui)
|
|
||||||
install(TARGETS wind DESTINATION ${LUNA_BASE}/usr/bin)
|
|
@ -1,21 +0,0 @@
|
|||||||
#include "Mouse.h"
|
|
||||||
|
|
||||||
Mouse::Mouse(ui::Canvas& screen)
|
|
||||||
{
|
|
||||||
m_position.x = screen.width / 2;
|
|
||||||
m_position.y = screen.height / 2;
|
|
||||||
m_screen_rect = screen.rect();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Mouse::draw(ui::Canvas& screen)
|
|
||||||
{
|
|
||||||
auto canvas = screen.subcanvas(m_position, 10, 10, true).release_value();
|
|
||||||
canvas.fill(ui::WHITE);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Mouse::move(const moon::MousePacket& packet)
|
|
||||||
{
|
|
||||||
m_position.x += packet.xdelta;
|
|
||||||
m_position.y -= packet.ydelta;
|
|
||||||
m_position = m_screen_rect.normalize(m_position);
|
|
||||||
}
|
|
18
wind/Mouse.h
18
wind/Mouse.h
@ -1,18 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include "Screen.h"
|
|
||||||
#include <moon/Mouse.h>
|
|
||||||
#include <ui/Canvas.h>
|
|
||||||
|
|
||||||
class Mouse
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
Mouse(ui::Canvas& screen);
|
|
||||||
|
|
||||||
void move(const moon::MousePacket& packet);
|
|
||||||
|
|
||||||
void draw(ui::Canvas& screen);
|
|
||||||
|
|
||||||
private:
|
|
||||||
ui::Point m_position;
|
|
||||||
ui::Rect m_screen_rect;
|
|
||||||
};
|
|
@ -1,34 +0,0 @@
|
|||||||
#include "Screen.h"
|
|
||||||
#include <errno.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <sys/ioctl.h>
|
|
||||||
#include <sys/mman.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
Result<Screen> Screen::open()
|
|
||||||
{
|
|
||||||
int fd = ::open("/dev/fb0", O_RDWR | O_CLOEXEC);
|
|
||||||
if (fd < 0) return err(errno);
|
|
||||||
|
|
||||||
int width = ioctl(fd, FB_GET_WIDTH);
|
|
||||||
int height = ioctl(fd, FB_GET_HEIGHT);
|
|
||||||
|
|
||||||
void* p = mmap(nullptr, width * height * BYTES_PER_PIXEL, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
|
|
||||||
if (p == MAP_FAILED)
|
|
||||||
{
|
|
||||||
close(fd);
|
|
||||||
return err(errno);
|
|
||||||
}
|
|
||||||
|
|
||||||
Screen screen;
|
|
||||||
|
|
||||||
screen.m_canvas = ui::Canvas::create((u8*)p, width, height);
|
|
||||||
screen.m_size = width * height * BYTES_PER_PIXEL;
|
|
||||||
|
|
||||||
return screen;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Screen::sync()
|
|
||||||
{
|
|
||||||
msync(m_canvas.ptr, size(), MS_SYNC);
|
|
||||||
}
|
|
@ -1,27 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include <luna/OwnedPtr.h>
|
|
||||||
#include <ui/Canvas.h>
|
|
||||||
|
|
||||||
constexpr int BYTES_PER_PIXEL = 4;
|
|
||||||
|
|
||||||
class Screen
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
static Result<Screen> open();
|
|
||||||
|
|
||||||
ui::Canvas& canvas()
|
|
||||||
{
|
|
||||||
return m_canvas;
|
|
||||||
}
|
|
||||||
|
|
||||||
int size() const
|
|
||||||
{
|
|
||||||
return m_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
void sync();
|
|
||||||
|
|
||||||
private:
|
|
||||||
ui::Canvas m_canvas;
|
|
||||||
int m_size;
|
|
||||||
};
|
|
@ -1,98 +0,0 @@
|
|||||||
#include "Mouse.h"
|
|
||||||
#include "Screen.h"
|
|
||||||
#include <errno.h>
|
|
||||||
#include <moon/Keyboard.h>
|
|
||||||
#include <os/ArgumentParser.h>
|
|
||||||
#include <os/File.h>
|
|
||||||
#include <pwd.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <sys/ioctl.h>
|
|
||||||
#include <sys/poll.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
Result<int> luna_main(int argc, char** argv)
|
|
||||||
{
|
|
||||||
StringView socket_path = "/tmp/wind.sock";
|
|
||||||
StringView user;
|
|
||||||
|
|
||||||
os::ArgumentParser parser;
|
|
||||||
parser.add_description("The display server for Luna's graphical user interface."_sv);
|
|
||||||
parser.add_system_program_info("wind"_sv);
|
|
||||||
parser.add_value_argument(socket_path, 's', "socket"_sv, "the path for the local IPC socket"_sv);
|
|
||||||
parser.add_value_argument(user, 'u', "user"_sv, "the user to run as"_sv);
|
|
||||||
parser.parse(argc, argv);
|
|
||||||
|
|
||||||
if (geteuid() != 0)
|
|
||||||
{
|
|
||||||
os::eprintln("error: wind must be run as root to initialize resources, run with --user=<USERNAME> to drop "
|
|
||||||
"privileges afterwards");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto mouse = TRY(os::File::open("/dev/mouse", os::File::ReadOnly));
|
|
||||||
mouse->set_buffer(os::File::NotBuffered);
|
|
||||||
mouse->set_close_on_exec();
|
|
||||||
|
|
||||||
auto keyboard = TRY(os::File::open("/dev/kbd", os::File::ReadOnly));
|
|
||||||
keyboard->set_buffer(os::File::NotBuffered);
|
|
||||||
keyboard->set_close_on_exec();
|
|
||||||
|
|
||||||
auto screen = TRY(Screen::open());
|
|
||||||
|
|
||||||
Mouse mouse_pointer { screen.canvas() };
|
|
||||||
|
|
||||||
ioctl(STDIN_FILENO, TTYSETGFX, 1);
|
|
||||||
|
|
||||||
setpgid(0, 0);
|
|
||||||
|
|
||||||
int fd = open("/dev/null", O_RDONLY);
|
|
||||||
if (fd >= 0)
|
|
||||||
{
|
|
||||||
dup2(fd, STDIN_FILENO);
|
|
||||||
close(fd);
|
|
||||||
}
|
|
||||||
|
|
||||||
clearenv();
|
|
||||||
|
|
||||||
if (!user.is_empty())
|
|
||||||
{
|
|
||||||
auto* pwd = getpwnam(user.chars());
|
|
||||||
if (pwd)
|
|
||||||
{
|
|
||||||
setgid(pwd->pw_gid);
|
|
||||||
setuid(pwd->pw_uid);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ui::Color background = ui::BLACK;
|
|
||||||
|
|
||||||
while (1)
|
|
||||||
{
|
|
||||||
struct pollfd fds[] = {
|
|
||||||
{ .fd = mouse->fd(), .events = POLLIN, .revents = 0 },
|
|
||||||
{ .fd = keyboard->fd(), .events = POLLIN, .revents = 0 },
|
|
||||||
};
|
|
||||||
|
|
||||||
int rc = poll(fds, 2, 1000);
|
|
||||||
if (!rc) continue;
|
|
||||||
if (rc < 0) { os::println("poll: error: %s", strerror(errno)); }
|
|
||||||
|
|
||||||
if (fds[0].revents & POLLIN)
|
|
||||||
{
|
|
||||||
moon::MousePacket packet;
|
|
||||||
TRY(mouse->read_typed(packet));
|
|
||||||
mouse_pointer.move(packet);
|
|
||||||
}
|
|
||||||
if (fds[1].revents & POLLIN)
|
|
||||||
{
|
|
||||||
moon::KeyboardPacket packet;
|
|
||||||
TRY(keyboard->read_typed(packet));
|
|
||||||
background = ui::Color::from_rgb(0x00, 0x00, packet.key * 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
screen.canvas().fill(background);
|
|
||||||
mouse_pointer.draw(screen.canvas());
|
|
||||||
screen.sync();
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user