Skip to content

Commit

Permalink
Merge branch 'sysprog21:main' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
alanjian85 authored Nov 20, 2024
2 parents 607ce07 + c7bbcc7 commit a02f40c
Show file tree
Hide file tree
Showing 16 changed files with 866 additions and 105 deletions.
1 change: 1 addition & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
Copyright (c) 2004 Keith Packard
Copyright (c) 2024 National Cheng Kung University, Taiwan

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
18 changes: 17 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@ libtwin.a_files-y = \
src/pattern.c \
src/spline.c \
src/work.c \
src/draw.c \
src/hull.c \
src/icon.c \
src/pixmap.c \
Expand All @@ -61,6 +60,14 @@ libtwin.a_includes-y := \
libtwin.a_files-$(CONFIG_LOGGING) += src/log.c
libtwin.a_files-$(CONFIG_CURSOR) += src/cursor.c

# Renderer
libtwin.a_files-$(CONFIG_RENDERER_BUILTIN) += src/draw.c
libtwin.a_files-$(CONFIG_RENDERER_PIXMAN) += src/draw-pixman.c
libtwin.a_cflags-$(CONFIG_RENDERER_PIXMAN) += $(shell pkg-config --cflags pixman-1)
ifeq ($(CONFIG_RENDERER_PIXMAN), y)
TARGET_LIBS += $(shell pkg-config --libs pixman-1)
endif

# Image loaders

ifeq ($(CONFIG_LOADER_JPEG), y)
Expand Down Expand Up @@ -105,10 +112,19 @@ endif

ifeq ($(CONFIG_BACKEND_FBDEV), y)
BACKEND = fbdev
TARGET_LIBS += -ludev
libtwin.a_files-y += backend/fbdev.c
libtwin.a_files-y += backend/linux_input.c
endif

ifeq ($(CONFIG_BACKEND_VNC), y)
BACKEND = vnc
libtwin.a_files-y += backend/vnc.c
libtwin.a_files-y += src/cursor.c
libtwin.a_cflags-y += $(shell pkg-config --cflags neatvnc aml pixman-1)
TARGET_LIBS += $(shell pkg-config --libs neatvnc aml pixman-1)
endif

# Standalone application

ifeq ($(CONFIG_DEMO_APPLICATIONS), y)
Expand Down
41 changes: 35 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,15 +65,35 @@ benefiting the entire application stack.
`Mado` is built with a minimalist design in mind. However, its verification
relies on certain third-party packages for full functionality and access to all
its features. We encourage the development environment to be installed with all optional
packages, including [libjpeg](https://www.ijg.org/), [libpng](https://github.com/pnggroup/libpng),
and the [SDL2 library](https://www.libsdl.org/).
* macOS: `brew install sdl2 jpeg libpng`
* Ubuntu Linux / Debian: `sudo apt install libsdl2-dev libjpeg-dev libpng-dev`
packages, including [libjpeg](https://www.ijg.org/) and [libpng](https://github.com/pnggroup/libpng).
* macOS: `brew install jpeg libpng`
* Ubuntu Linux / Debian: `sudo apt install libjpeg-dev libpng-dev`

The renderer implementation can either use the built-in pixel manipulation or be based on [Pixman](https://pixman.org/).
The built-in renderer is simple and performs adequately on platforms without SIMD instructions,
such as RISC-V processors without vector extensions.
However, for modern CPU architectures with extensive ISA extensions, Pixman offers faster pixel manipulation.
Install [Pixman](https://pixman.org/) before selecting the corresponding renderer implementation.
* macOS: `brew install pixman`
* Ubuntu Linux / Debian: `sudo apt install libpixman-1-dev`

In the meantime, ensure that you choose a graphics backend and install the necessary packages beforehand.

For SDL backend, install the [SDL2 library](https://www.libsdl.org/).
* macOS: `brew install sdl2`
* Ubuntu Linux / Debian: `sudo apt install libsdl2-dev`

For the VNC backend, please note that it has only been tested on GNU/Linux, and the prebuilt [neatvnc](https://github.com/any1/neatvnc) package might be outdated. To ensure you have the latest version, you can build the required packages from source by running the script:
```shell
$ tools/build-neatvnc.sh
```

For Linux framebuffer backend, install `libudev` and `libuuid`:
* Ubuntu Linux / Debian: `sudo apt install libudev-dev uuid-dev`

### Configuration

Configure via [Kconfiglib](https://pypi.org/project/kconfiglib/), you should select either SDL
video output or the Linux framebuffer.
Configure via [Kconfiglib](https://pypi.org/project/kconfiglib/), you should select either SDL video, the Linux framebuffer, or VNC as the graphics backend.
```shell
$ make config
```
Expand Down Expand Up @@ -108,6 +128,15 @@ $ sudo usermod -a -G video $USERNAME

In addition, the framebuffer device can be assigned via the environment variable `FRAMEBUFFER`.

To run demo program with the VNC backend:

```shell
$ ./demo-vnc
```

This will start the VNC server. You can use any VNC client to connect using the specified IP address (default is `127.0.0.1`) and port (default is `5900`).
The IP address can be set using the `MADO_VNC_HOST` environment variable, and the port can be configured using `MADO_VNC_PORT`.

## License

`Mado` is available under a MIT-style license, permitting liberal commercial use.
Expand Down
58 changes: 5 additions & 53 deletions backend/fbdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,14 @@

#include <fcntl.h>
#include <linux/fb.h>
#include <linux/kd.h>
#include <linux/vt.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <twin.h>
#include <unistd.h>

#include "linux_input.h"
#include "linux_vt.h"
#include "twin_backend.h"
#include "twin_private.h"

Expand All @@ -31,8 +30,6 @@ typedef struct {

/* Linux virtual terminal (VT) */
int vt_fd;
int vt_num;
bool vt_active;

/* Linux framebuffer */
int fb_fd;
Expand All @@ -58,8 +55,8 @@ static void _twin_fbdev_put_span(twin_coord_t left,
twin_coord_t width = right - left;
off_t off = top * screen->width + left;
uint32_t *dest =
(uint32_t *) ((uintptr_t) tx->fb_base + (off * sizeof(uint32_t)));
memcpy(dest, pixels, width * sizeof(uint32_t));
(uint32_t *) ((uintptr_t) tx->fb_base + (off * sizeof(*dest)));
memcpy(dest, pixels, width * sizeof(*dest));
}

static void twin_fbdev_get_screen_size(twin_fbdev_t *tx,
Expand Down Expand Up @@ -139,51 +136,6 @@ static bool twin_fbdev_apply_config(twin_fbdev_t *tx)
return true;
}

static int twin_vt_open(int vt_num)
{
int fd;

char vt_dev[30] = {0};
snprintf(vt_dev, 30, "/dev/tty%d", vt_num);

fd = open(vt_dev, O_RDWR);
if (fd < 0) {
log_error("Failed to open %s", vt_dev);
}

return fd;
}

static bool twin_vt_setup(twin_fbdev_t *tx)
{
/* Open VT0 to inquire information */
if ((tx->vt_fd = twin_vt_open(0)) < -1) {
log_error("Failed to open VT0");
return false;
}

/* Inquire for current VT number */
struct vt_stat vt;
if (ioctl(tx->vt_fd, VT_GETSTATE, &vt) == -1) {
log_error("Failed to get VT number");
return false;
}
tx->vt_num = vt.v_active;

/* Open the VT */
if ((tx->vt_fd = twin_vt_open(tx->vt_num)) < -1) {
return false;
}

/* Set VT to graphics mode to inhibit command-line text */
if (ioctl(tx->vt_fd, KDSETMODE, KD_GRAPHICS) < 0) {
log_error("Failed to set KD_GRAPHICS mode");
return false;
}

return true;
}

twin_context_t *twin_fbdev_init(int width, int height)
{
char *fbdev_path = getenv(FBDEV_NAME);
Expand All @@ -210,7 +162,7 @@ twin_context_t *twin_fbdev_init(int width, int height)
}

/* Set up virtual terminal environment */
if (!twin_vt_setup(tx)) {
if (!twin_vt_setup(&tx->vt_fd)) {
goto bail_fb_fd;
}

Expand Down Expand Up @@ -262,7 +214,7 @@ static void twin_fbdev_exit(twin_context_t *ctx)
return;

twin_fbdev_t *tx = PRIV(ctx);
ioctl(tx->vt_fd, KDSETMODE, KD_TEXT);
twin_vt_mode(tx->vt_fd, KD_TEXT);
munmap(tx->fb_base, tx->fb_len);
twin_linux_input_destroy(tx->input);
close(tx->vt_fd);
Expand Down
Loading

0 comments on commit a02f40c

Please sign in to comment.