umka_os: send mouse events to the kernel
This commit is contained in:
5
README
5
README
@@ -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
13
TODO
@@ -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
|
||||
|
2
makefile
2
makefile
@@ -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
163
shell.c
@@ -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
120
shell.h
@@ -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
124
umka_os.c
@@ -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;
|
||||
}
|
||||
|
Reference in New Issue
Block a user