umka_os: send mouse events to the kernel

This commit is contained in:
2025-01-20 04:24:08 +00:00
parent 4068524e00
commit b8269949ed
6 changed files with 278 additions and 149 deletions

5
README
View File

@@ -103,6 +103,11 @@ Testing
Troubleshooting
---------------
# Build
Install toolchain for the 32-bit target, e.g. gcc-multilib, lib32-glibc,
32-bit and develop packages of libfuse and libsdl2, fasm.
# umka_os
To create tap devices.

13
TODO
View File

@@ -1,9 +1,10 @@
make mkfs.* use config files (-c for mkfs.xfs)
export and initialize mouse_delay and mouse_speed_factor (test and cover func mouse_acceleration)
lsstat to decrease tests size
separate dirs for each image and test
separate dirs for each image
include umka_os to tests
tests with writing to block devices (read-only base image + discardable image for writing)
library loader
custom test runner
make mkfs.xfs use config file via -c option
writing tests
compare with reference XFS implementation
stressing via ref impl
validate against the reference XFS implementation
stressing via ref impl (how?)
multithreaded: kofu one.t two.t

View File

@@ -84,7 +84,7 @@ umka_os: umka_os.o umka.o shell.o deps/lodepng/lodepng.o vdisk.o vdisk/raw.o \
vnet/file.o vnet/null.o trace.o trace_lbr.o $(HOST)/pci.o \
$(HOST)/thread.o umkaio.o umkart.o deps/isocline/src/isocline.o \
deps/optparse/optparse.o
$(CC) $(LDFLAGS_32) `sdl2-config --libs` $^ -o $@ -T umka.ld
$(CC) $(LDFLAGS_32) $^ `sdl2-config --libs` -o $@ -T umka.ld
umka_gen_devices_dat: umka_gen_devices_dat.o umka.o $(HOST)/pci.o \
$(HOST)/thread.o umkart.o

163
shell.c
View File

@@ -51,124 +51,12 @@
#define SHELL_CMD_BUF_LEN 0x10
enum {
UMKA_CMD_NONE,
UMKA_CMD_SET_MOUSE_DATA,
UMKA_CMD_WAIT_FOR_IDLE,
UMKA_CMD_WAIT_FOR_OS_IDLE,
UMKA_CMD_WAIT_FOR_WINDOW,
UMKA_CMD_SYS_CSLEEP,
UMKA_CMD_SYS_PROCESS_INFO,
UMKA_CMD_SYS_GET_MOUSE_POS_SCREEN,
UMKA_CMD_SYS_LFN,
};
enum {
SHELL_CMD_STATUS_EMPTY,
SHELL_CMD_STATUS_READY,
SHELL_CMD_STATUS_DONE,
};
struct cmd_set_mouse_data_arg {
uint32_t btn_state;
int32_t xmoving;
int32_t ymoving;
int32_t vscroll;
int32_t hscroll;
};
struct cmd_set_mouse_data_ret {
char stub;
};
struct cmd_set_mouse_data {
struct cmd_set_mouse_data_arg arg;
struct cmd_set_mouse_data_ret ret;
};
struct cmd_sys_lfn_arg {
f70or80_t f70or80;
f7080s1arg_t *bufptr;
f7080ret_t *r;
};
struct cmd_sys_lfn_ret {
f7080ret_t status;
};
struct cmd_sys_lfn {
struct cmd_sys_lfn_arg arg;
struct cmd_sys_lfn_ret ret;
};
struct cmd_sys_process_info_arg {
int32_t pid;
void *param;
};
struct cmd_sys_process_info_ret {
char stub;
};
struct cmd_sys_process_info {
struct cmd_sys_process_info_arg arg;
struct cmd_sys_process_info_ret ret;
};
struct cmd_sys_get_mouse_pos_screen_arg {
char stub;
};
struct cmd_sys_get_mouse_pos_screen_ret {
struct point16s pos;
};
struct cmd_sys_get_mouse_pos_screen {
struct cmd_sys_get_mouse_pos_screen_arg arg;
struct cmd_sys_get_mouse_pos_screen_ret ret;
};
struct cmd_sys_csleep_arg {
uint32_t csec;
};
struct cmd_sys_csleep_ret {
char stub;
};
struct cmd_sys_csleep {
struct cmd_sys_csleep_arg arg;
struct cmd_sys_csleep_ret ret;
};
struct cmd_wait_for_window_arg {
char *wnd_title;
};
struct cmd_wait_for_window_ret {
char stub;
};
struct cmd_wait_for_window {
struct cmd_wait_for_window_arg arg;
struct cmd_wait_for_window_ret ret;
};
struct umka_cmd {
atomic_int status;
uint32_t type;
union {
// internal funcs
struct cmd_set_mouse_data set_mouse_data;
struct cmd_wait_for_window wait_for_window;
// syscalls
struct cmd_sys_csleep sys_csleep;
struct cmd_sys_process_info sys_process_info;
struct cmd_sys_lfn sys_lfn;
struct cmd_sys_get_mouse_pos_screen sys_get_mouse_pos_screen;
};
};
struct umka_cmd umka_cmd_buf[SHELL_CMD_BUF_LEN];
char prompt_line[PATH_MAX];
@@ -181,21 +69,6 @@ typedef struct {
void (*func) (struct shell_ctx *, int, char **);
} func_table_t;
void
shell_run_cmd_sync(struct shell_ctx *ctx);
static void
shell_run_cmd(struct shell_ctx *ctx) {
struct umka_cmd *cmd = umka_cmd_buf;
atomic_store_explicit(&cmd->status, SHELL_CMD_STATUS_READY,
memory_order_release);
if (atomic_load_explicit(ctx->running, memory_order_acquire) == UMKA_RUNNING_YES) {
pthread_cond_wait(&ctx->cmd_done, &ctx->cmd_mutex);
} else {
shell_run_cmd_sync(ctx);
}
}
static uint32_t
shell_run_cmd_wait_test(void /* struct appdata * with wait_param is in ebx */) {
appdata_t *app;
@@ -204,6 +77,9 @@ shell_run_cmd_wait_test(void /* struct appdata * with wait_param is in ebx */) {
return (uint32_t)(atomic_load_explicit(&cmd->status, memory_order_acquire) == SHELL_CMD_STATUS_READY);
}
static void
shell_run_cmd_sync(struct shell_ctx *ctx);
static void
thread_cmd_runner(void *arg) {
umka_sti();
@@ -1387,17 +1263,16 @@ cmd_mouse_move(struct shell_ctx *ctx, int argc, char **argv) {
}
uint32_t btn_state = lbheld + (rbheld << 1) + (mbheld << 2) + (yabs << 30)
+ (xabs << 31);
struct umka_cmd *cmd = umka_cmd_buf;
struct cmd_set_mouse_data_arg *c = &cmd->set_mouse_data.arg;
struct umka_cmd *cmd = shell_get_cmd(ctx);
cmd->type = UMKA_CMD_SET_MOUSE_DATA;
struct cmd_set_mouse_data_arg *c = &cmd->set_mouse_data.arg;
c->btn_state = btn_state;
c->xmoving = xmoving;
c->ymoving = ymoving;
c->vscroll = vscroll;
c->hscroll = hscroll;
shell_run_cmd(ctx);
atomic_store_explicit(&cmd->status, SHELL_CMD_STATUS_EMPTY,
memory_order_release);
shell_clear_cmd(cmd);
}
static void
@@ -4330,7 +4205,7 @@ func_table_t cmd_cmds[] = {
{ NULL, NULL },
};
void
static void
shell_run_cmd_sync(struct shell_ctx *ctx) {
struct umka_cmd *cmd = umka_cmd_buf;
switch (cmd->type) {
@@ -4384,6 +4259,30 @@ shell_run_cmd_sync(struct shell_ctx *ctx) {
pthread_cond_signal(&ctx->cmd_done);
}
struct umka_cmd *
shell_get_cmd(struct shell_ctx *shell) {
(void)shell;
return umka_cmd_buf;
}
void
shell_run_cmd(struct shell_ctx *ctx) {
struct umka_cmd *cmd = umka_cmd_buf;
atomic_store_explicit(&cmd->status, SHELL_CMD_STATUS_READY,
memory_order_release);
if (atomic_load_explicit(ctx->running, memory_order_acquire) == UMKA_RUNNING_YES) {
pthread_cond_wait(&ctx->cmd_done, &ctx->cmd_mutex);
} else {
shell_run_cmd_sync(ctx);
}
}
void
shell_clear_cmd(struct umka_cmd *cmd) {
atomic_store_explicit(&cmd->status, SHELL_CMD_STATUS_EMPTY,
memory_order_release);
}
static void
cmd_help(struct shell_ctx *ctx, int argc, char **argv) {
const char *usage = \

120
shell.h
View File

@@ -59,7 +59,125 @@ shell_close(struct shell_ctx *shell);
void *
run_test(struct shell_ctx *ctx);
enum {
UMKA_CMD_NONE,
UMKA_CMD_SET_MOUSE_DATA,
UMKA_CMD_WAIT_FOR_IDLE,
UMKA_CMD_WAIT_FOR_OS_IDLE,
UMKA_CMD_WAIT_FOR_WINDOW,
UMKA_CMD_SYS_CSLEEP,
UMKA_CMD_SYS_PROCESS_INFO,
UMKA_CMD_SYS_GET_MOUSE_POS_SCREEN,
UMKA_CMD_SYS_LFN,
};
struct cmd_set_mouse_data_arg {
uint32_t btn_state;
int32_t xmoving;
int32_t ymoving;
int32_t vscroll;
int32_t hscroll;
};
struct cmd_set_mouse_data_ret {
char stub;
};
struct cmd_set_mouse_data {
struct cmd_set_mouse_data_arg arg;
struct cmd_set_mouse_data_ret ret;
};
struct cmd_sys_lfn_arg {
f70or80_t f70or80;
f7080s1arg_t *bufptr;
f7080ret_t *r;
};
struct cmd_sys_lfn_ret {
f7080ret_t status;
};
struct cmd_sys_lfn {
struct cmd_sys_lfn_arg arg;
struct cmd_sys_lfn_ret ret;
};
struct cmd_sys_process_info_arg {
int32_t pid;
void *param;
};
struct cmd_sys_process_info_ret {
char stub;
};
struct cmd_sys_process_info {
struct cmd_sys_process_info_arg arg;
struct cmd_sys_process_info_ret ret;
};
struct cmd_sys_get_mouse_pos_screen_arg {
char stub;
};
struct cmd_sys_get_mouse_pos_screen_ret {
struct point16s pos;
};
struct cmd_sys_get_mouse_pos_screen {
struct cmd_sys_get_mouse_pos_screen_arg arg;
struct cmd_sys_get_mouse_pos_screen_ret ret;
};
struct cmd_sys_csleep_arg {
uint32_t csec;
};
struct cmd_sys_csleep_ret {
char stub;
};
struct cmd_sys_csleep {
struct cmd_sys_csleep_arg arg;
struct cmd_sys_csleep_ret ret;
};
struct cmd_wait_for_window_arg {
char *wnd_title;
};
struct cmd_wait_for_window_ret {
char stub;
};
struct cmd_wait_for_window {
struct cmd_wait_for_window_arg arg;
struct cmd_wait_for_window_ret ret;
};
struct umka_cmd {
atomic_int status;
uint32_t type;
union {
// internal funcs
struct cmd_set_mouse_data set_mouse_data;
struct cmd_wait_for_window wait_for_window;
// syscalls
struct cmd_sys_csleep sys_csleep;
struct cmd_sys_process_info sys_process_info;
struct cmd_sys_lfn sys_lfn;
struct cmd_sys_get_mouse_pos_screen sys_get_mouse_pos_screen;
};
};
struct umka_cmd *
shell_get_cmd(struct shell_ctx *shell);
void
umka_run_cmd_sync(struct shell_ctx *ctx);
shell_run_cmd(struct shell_ctx *ctx);
void
shell_clear_cmd(struct umka_cmd *cmd);
#endif // SHELL_H_INCLUDED

124
umka_os.c
View File

@@ -154,6 +154,17 @@ hw_int(int signo) {
umka_sti();
}
void (*copy_display)(void *);
static void
update_display(SDL_Surface *window_surface, SDL_Window *window) {
SDL_LockSurface(window_surface);
copy_display(window_surface->pixels);
SDL_UnlockSurface(window_surface);
SDL_UpdateWindowSurface(window);
return;
}
static void *
umka_display(void *arg) {
(void)arg;
@@ -164,8 +175,8 @@ umka_display(void *arg) {
}
char title[64];
sprintf(title, "umka0 %ux%u %ubpp", kos_display.width, kos_display.height,
kos_display.bits_per_pixel);
sprintf(title, "umka %ux%u %ubpp, press Ctrl-Alt-g to (un)grab input",
kos_display.width, kos_display.height, kos_display.bits_per_pixel);
SDL_Window *window = SDL_CreateWindow(title,
SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED,
@@ -187,8 +198,6 @@ umka_display(void *arg) {
return NULL;
}
void (*copy_display)(void *) = NULL;
switch (window_surface->format->format) {
case SDL_PIXELFORMAT_RGB888:
copy_display = copy_display_to_rgb888;
@@ -199,12 +208,109 @@ umka_display(void *arg) {
break;
}
bool input_grabbed = false;
SDL_Event event;
while (1) {
SDL_LockSurface(window_surface);
copy_display(window_surface->pixels);
SDL_UnlockSurface(window_surface);
SDL_UpdateWindowSurface(window);
sleep(1);
struct umka_cmd *cmd;
struct cmd_set_mouse_data_arg *c;
uint32_t btn_state;
update_display(window_surface, window);
if (SDL_WaitEventTimeout(&event, 1000 /* ms */)) {
switch (event.type) {
case SDL_QUIT:
break;
case SDL_WINDOWEVENT:
break;
case SDL_MOUSEBUTTONDOWN:
case SDL_MOUSEBUTTONUP:
if (!input_grabbed) {
break;
}
cmd = shell_get_cmd(os->shell);
cmd->type = UMKA_CMD_SET_MOUSE_DATA;
c = &cmd->set_mouse_data.arg;
c->btn_state = event.button.state;
c->xmoving = 0;
c->ymoving = 0;
c->vscroll = 0;
c->hscroll = 0;
shell_run_cmd(os->shell);
shell_clear_cmd(cmd);
break;
case SDL_MOUSEMOTION:
if (!input_grabbed) {
break;
}
cmd = shell_get_cmd(os->shell);
cmd->type = UMKA_CMD_SET_MOUSE_DATA;
c = &cmd->set_mouse_data.arg;
c->btn_state = 0;
c->xmoving = event.motion.xrel;
c->ymoving = -event.motion.yrel;
c->vscroll = 0;
c->hscroll = 0;
shell_run_cmd(os->shell);
shell_clear_cmd(cmd);
break;
case SDL_MOUSEWHEEL:
if (!input_grabbed) {
break;
}
btn_state = SDL_GetMouseState(NULL, NULL);
cmd = shell_get_cmd(os->shell);
cmd->type = UMKA_CMD_SET_MOUSE_DATA;
c = &cmd->set_mouse_data.arg;
c->btn_state = 0;
if ((btn_state & SDL_BUTTON_LMASK)) {
c->btn_state |= 0x01;
}
/*
if ((btn_state & SDL_BUTTON_RMASK)) {
c->btn_state |= 0x02;
}
if ((btn_state & SDL_BUTTON_MMASK)) {
c->btn_state |= 0x04;
}
*/
c->xmoving = 0;
c->ymoving = 0;
c->vscroll = event.wheel.y;
c->hscroll = event.wheel.x;
shell_run_cmd(os->shell);
shell_clear_cmd(cmd);
break;
case SDL_KEYDOWN:
if ((event.key.keysym.scancode == SDL_SCANCODE_G)
&& (event.key.keysym.mod & KMOD_CTRL)
&& (event.key.keysym.mod & KMOD_ALT)) {
input_grabbed = !input_grabbed;
SDL_SetWindowMouseGrab(window, input_grabbed);
SDL_SetWindowKeyboardGrab(window, input_grabbed);
SDL_SetRelativeMouseMode(input_grabbed);
}
if (!input_grabbed) {
break;
}
break;
case SDL_KEYUP:
if (!input_grabbed) {
break;
}
break;
case SDL_TEXTINPUT:
if (!input_grabbed) {
break;
}
break;
default:
fprintf(stderr, "[sdl] unknown event type: 0x%x\n", event.type);
update_display(window_surface, window);
}
} else {
update_display(window_surface, window);
}
// sleep(1);
}
return NULL;
}