First pass at a select-like fs wait function
This commit is contained in:
parent
9345487324
commit
665343e636
@ -71,6 +71,20 @@ static inline void pipe_increment_write_by(pipe_device_t * pipe, size_t amount)
|
||||
pipe->write_ptr = (pipe->write_ptr + amount) % pipe->size;
|
||||
}
|
||||
|
||||
static void pipe_alert_waiters(fs_node_t * fs_node) {
|
||||
pipe_device_t * pipe = (pipe_device_t *)fs_node->device;
|
||||
|
||||
if (pipe->alert_waiters) {
|
||||
while (pipe->alert_waiters->head) {
|
||||
node_t * node = list_dequeue(pipe->alert_waiters);
|
||||
process_t * p = node->value;
|
||||
process_alert_node(p, fs_node);
|
||||
free(node);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t read_pipe(fs_node_t *node, uint32_t offset, uint32_t size, uint8_t *buffer) {
|
||||
assert(node->device != 0 && "Attempted to read from a fully-closed pipe.");
|
||||
|
||||
@ -166,6 +180,7 @@ uint32_t write_pipe(fs_node_t *node, uint32_t offset, uint32_t size, uint8_t *bu
|
||||
|
||||
spin_unlock(pipe->lock_write);
|
||||
wakeup_queue(pipe->wait_queue_readers);
|
||||
pipe_alert_waiters(node);
|
||||
if (written < size) {
|
||||
sleep_on(pipe->wait_queue_writers);
|
||||
}
|
||||
@ -211,10 +226,39 @@ void close_pipe(fs_node_t * node) {
|
||||
return;
|
||||
}
|
||||
|
||||
static int pipe_check(fs_node_t * node) {
|
||||
pipe_device_t * pipe = (pipe_device_t *)node->device;
|
||||
|
||||
if (pipe_unread(pipe) > 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int pipe_wait(fs_node_t * node, void * process) {
|
||||
pipe_device_t * pipe = (pipe_device_t *)node->device;
|
||||
|
||||
if (!pipe->alert_waiters) {
|
||||
pipe->alert_waiters = list_create();
|
||||
}
|
||||
|
||||
list_insert(pipe->alert_waiters, process);
|
||||
list_insert(((process_t *)process)->node_waits, pipe);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int pipe_match(fs_node_t * node, void * value) {
|
||||
pipe_device_t * pipe = (pipe_device_t *)node->device;
|
||||
return pipe == value;
|
||||
}
|
||||
|
||||
fs_node_t * make_pipe(size_t size) {
|
||||
fs_node_t * fnode = malloc(sizeof(fs_node_t));
|
||||
pipe_device_t * pipe = malloc(sizeof(pipe_device_t));
|
||||
memset(fnode, 0, sizeof(fs_node_t));
|
||||
memset(pipe, 0, sizeof(pipe_device_t));
|
||||
|
||||
fnode->device = 0;
|
||||
fnode->name[0] = '\0';
|
||||
@ -232,6 +276,10 @@ fs_node_t * make_pipe(size_t size) {
|
||||
fnode->ioctl = NULL; /* TODO ioctls for pipes? maybe */
|
||||
fnode->get_size = pipe_size;
|
||||
|
||||
fnode->selectcheck = pipe_check;
|
||||
fnode->selectwait = pipe_wait;
|
||||
fnode->match = pipe_match;
|
||||
|
||||
fnode->atime = now();
|
||||
fnode->mtime = fnode->atime;
|
||||
fnode->ctime = fnode->atime;
|
||||
|
@ -89,6 +89,41 @@ static fs_node_t * vfs_mapper(void) {
|
||||
return fnode;
|
||||
}
|
||||
|
||||
/**
|
||||
* selectcheck_fs: Check if a read from this file would block.
|
||||
*/
|
||||
int selectcheck_fs(fs_node_t * node) {
|
||||
if (!node) return -1;
|
||||
|
||||
if (node->selectcheck) {
|
||||
return node->selectcheck(node);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* selectwait_fs: Inform a node that it should alert the current_process.
|
||||
*/
|
||||
int selectwait_fs(fs_node_t * node, void * process) {
|
||||
if (!node) return -1;
|
||||
|
||||
if (node->selectwait) {
|
||||
return node->selectwait(node, process);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* fsnode_matches: Compare a node internally against a magic value to determine if the value belongs to that node.
|
||||
*/
|
||||
int fsnode_matches(fs_node_t * node, void * value) {
|
||||
if (!node) return 0;
|
||||
if (!node->match) return 0;
|
||||
return node->match(node, value);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* read_fs: Read a file system node based on its underlying type.
|
||||
|
@ -51,6 +51,9 @@ typedef int (*get_size_type_t) (struct fs_node *);
|
||||
typedef int (*chmod_type_t) (struct fs_node *, int mode);
|
||||
typedef void (*symlink_type_t) (struct fs_node *, char * name, char * value);
|
||||
typedef int (*readlink_type_t) (struct fs_node *, char * buf, size_t size);
|
||||
typedef int (*selectcheck_type_t) (struct fs_node *);
|
||||
typedef int (*selectwait_type_t) (struct fs_node *, void * process);
|
||||
typedef int (*match_type_t) (struct fs_node *, void * value);
|
||||
|
||||
typedef struct fs_node {
|
||||
char name[256]; /* The filename. */
|
||||
@ -89,6 +92,10 @@ typedef struct fs_node {
|
||||
uint32_t offset; /* Offset for read operations XXX move this to new "file descriptor" entry */
|
||||
int32_t refcount;
|
||||
uint32_t nlink;
|
||||
|
||||
selectcheck_type_t selectcheck;
|
||||
selectwait_type_t selectwait;
|
||||
match_type_t match;
|
||||
} fs_node_t;
|
||||
|
||||
struct dirent {
|
||||
@ -140,6 +147,9 @@ int chmod_fs(fs_node_t *node, int mode);
|
||||
int unlink_fs(char * name);
|
||||
int symlink_fs(char * value, char * name);
|
||||
int readlink_fs(fs_node_t * node, char * buf, size_t size);
|
||||
int selectcheck_fs(fs_node_t * node);
|
||||
int selectwait_fs(fs_node_t * node, void * process);
|
||||
int fsnode_matches(fs_node_t * node, void * value);
|
||||
|
||||
void vfs_install(void);
|
||||
void * vfs_mount(char * path, fs_node_t * local_root);
|
||||
|
@ -19,6 +19,7 @@ typedef struct _pipe_device {
|
||||
list_t * wait_queue_readers;
|
||||
list_t * wait_queue_writers;
|
||||
int dead;
|
||||
list_t * alert_waiters;
|
||||
} pipe_device_t;
|
||||
|
||||
fs_node_t * make_pipe(size_t size);
|
||||
|
@ -103,6 +103,8 @@ typedef struct process {
|
||||
node_t * timed_sleep_node;
|
||||
uint8_t is_tasklet;
|
||||
volatile uint8_t sleep_interrupted;
|
||||
list_t * node_waits;
|
||||
int awoken_index;
|
||||
} process_t;
|
||||
|
||||
typedef struct {
|
||||
@ -134,6 +136,9 @@ extern volatile process_t * current_process;
|
||||
extern process_t * kernel_idle_task;
|
||||
extern list_t * process_list;
|
||||
|
||||
extern int process_wait_nodes(process_t * process,fs_node_t * nodes[]);
|
||||
extern int process_alert_node(process_t * process, fs_node_t * fs_node);
|
||||
|
||||
typedef void (*tasklet_t) (void *, char *);
|
||||
extern int create_kernel_tasklet(tasklet_t tasklet, char * name, void * argp);
|
||||
|
||||
|
@ -814,3 +814,59 @@ int waitpid(int pid, int * status, int options) {
|
||||
} while (1);
|
||||
}
|
||||
|
||||
int process_wait_nodes(process_t * process,fs_node_t * nodes[]) {
|
||||
assert(!process->node_waits && "Tried to wait on nodes while already waiting on nodes.");
|
||||
assert(nodes[0] && "Empty wait list.");
|
||||
|
||||
fs_node_t ** n = nodes;
|
||||
int index = 0;
|
||||
do {
|
||||
int result = selectcheck_fs(*n);
|
||||
if (result < 0) {
|
||||
debug_print(NOTICE, "An invalid descriptor was specified: %d (0x%x)", index, *n);
|
||||
return -1;
|
||||
}
|
||||
if (result == 0) {
|
||||
return index;
|
||||
}
|
||||
n++;
|
||||
index++;
|
||||
} while (*n);
|
||||
|
||||
n = nodes;
|
||||
process->node_waits = list_create();
|
||||
do {
|
||||
if (selectwait_fs(*n, process) < 0) {
|
||||
debug_print(NOTICE, "Bad selectwait? 0x%x", *n);
|
||||
}
|
||||
n++;
|
||||
} while (*n);
|
||||
|
||||
process->awoken_index = -1;
|
||||
/* Wait. */
|
||||
switch_task(0);
|
||||
|
||||
return process->awoken_index;
|
||||
}
|
||||
|
||||
int process_alert_node(process_t * process, fs_node_t * fs_node) {
|
||||
if (!process->node_waits) {
|
||||
return 0; /* Possibly already returned. Wait for another call. */
|
||||
}
|
||||
|
||||
int index = 0;
|
||||
foreach(node, process->node_waits) {
|
||||
if (fsnode_matches(fs_node, node->value)) {
|
||||
process->awoken_index = index;
|
||||
list_free(process->node_waits);
|
||||
free(process->node_waits);
|
||||
process->node_waits = NULL;
|
||||
make_process_ready(process);
|
||||
return 0;
|
||||
}
|
||||
index++;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -787,6 +787,22 @@ static int sys_lstat(char * file, uintptr_t st) {
|
||||
return result;
|
||||
}
|
||||
|
||||
static int sys_fswait(int c, int fds[]) {
|
||||
PTR_VALIDATE(fds);
|
||||
for (int i = 0; i < c; ++i) {
|
||||
if (!FD_CHECK(fds[i])) return -1;
|
||||
}
|
||||
fs_node_t ** nodes = malloc(sizeof(fs_node_t *)*(c+1));
|
||||
for (int i = 0; i < c; ++i) {
|
||||
nodes[i] = FD_ENTRY(fds[i]);
|
||||
}
|
||||
nodes[c] = NULL;
|
||||
|
||||
int result = process_wait_nodes((process_t *)current_process, nodes);
|
||||
free(nodes);
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* System Call Internals
|
||||
*/
|
||||
@ -839,6 +855,7 @@ static int (*syscalls[])() = {
|
||||
[SYS_SYMLINK] = sys_symlink,
|
||||
[SYS_READLINK] = sys_readlink,
|
||||
[SYS_LSTAT] = sys_lstat,
|
||||
[SYS_FSWAIT] = sys_fswait,
|
||||
};
|
||||
|
||||
uint32_t num_syscalls = sizeof(syscalls) / sizeof(*syscalls);
|
||||
|
@ -238,6 +238,32 @@ static void close_client(fs_node_t * node) {
|
||||
free(c);
|
||||
}
|
||||
|
||||
static int match_server(fs_node_t * node, void * value) {
|
||||
pex_ex_t * p = (pex_ex_t *)node->device;
|
||||
return fsnode_matches(p->server_pipe,value);
|
||||
}
|
||||
static int wait_server(fs_node_t * node, void * process) {
|
||||
pex_ex_t * p = (pex_ex_t *)node->device;
|
||||
return selectwait_fs(p->server_pipe, process);
|
||||
}
|
||||
static int check_server(fs_node_t * node) {
|
||||
pex_ex_t * p = (pex_ex_t *)node->device;
|
||||
return selectcheck_fs(p->server_pipe);
|
||||
}
|
||||
|
||||
static int match_client(fs_node_t * node, void * value) {
|
||||
pex_client_t * c = (pex_client_t *)node->inode;
|
||||
return fsnode_matches(c->pipe, value);
|
||||
}
|
||||
static int wait_client(fs_node_t * node, void * process) {
|
||||
pex_client_t * c = (pex_client_t *)node->inode;
|
||||
return selectwait_fs(c->pipe, process);
|
||||
}
|
||||
static int check_client(fs_node_t * node) {
|
||||
pex_client_t * c = (pex_client_t *)node->inode;
|
||||
return selectcheck_fs(c->pipe);
|
||||
}
|
||||
|
||||
static void open_pex(fs_node_t * node, unsigned int flags) {
|
||||
pex_ex_t * t = (pex_ex_t *)(node->device);
|
||||
|
||||
@ -250,6 +276,9 @@ static void open_pex(fs_node_t * node, unsigned int flags) {
|
||||
node->read = read_server;
|
||||
node->write = write_server;
|
||||
node->ioctl = ioctl_server;
|
||||
node->selectcheck = check_server;
|
||||
node->selectwait = wait_server;
|
||||
node->match = match_server;
|
||||
debug_print(INFO, "[pex] Server launched: %s", t->name);
|
||||
debug_print(INFO, "fs_node = 0x%x", node);
|
||||
} else if (!(flags & O_CREAT)) {
|
||||
@ -261,6 +290,10 @@ static void open_pex(fs_node_t * node, unsigned int flags) {
|
||||
node->ioctl = ioctl_client;
|
||||
node->close = close_client;
|
||||
|
||||
node->selectcheck = check_client;
|
||||
node->selectwait = wait_client;
|
||||
node->match = match_client;
|
||||
|
||||
list_insert(t->clients, client);
|
||||
|
||||
/* XXX: Send plumbing message to server for new client connection */
|
||||
@ -272,7 +305,6 @@ static void open_pex(fs_node_t * node, unsigned int flags) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
static struct dirent * readdir_packetfs(fs_node_t *node, uint32_t index) {
|
||||
pex_t * p = (pex_t *)node->device;
|
||||
unsigned int i = 0;
|
||||
|
@ -45,3 +45,4 @@
|
||||
#define SYS_SYMLINK 56
|
||||
#define SYS_READLINK 57
|
||||
#define SYS_LSTAT 58
|
||||
#define SYS_FSWAIT 59
|
||||
|
@ -476,106 +476,10 @@ static void server_window_resize_finish(yutani_globals_t * yg, yutani_server_win
|
||||
mark_window(yg, win);
|
||||
}
|
||||
|
||||
/**
|
||||
* Nested Yutani input thread
|
||||
*
|
||||
* Handles keyboard and mouse events, as well as
|
||||
* other Yutani events from the nested window.
|
||||
*/
|
||||
void * nested_input(void * _yg) {
|
||||
|
||||
yutani_globals_t * yg = _yg;
|
||||
|
||||
yutani_t * y = yutani_init();
|
||||
|
||||
while (1) {
|
||||
yutani_msg_t * m = yutani_poll(yg->host_context);
|
||||
if (m) {
|
||||
switch (m->type) {
|
||||
case YUTANI_MSG_KEY_EVENT:
|
||||
{
|
||||
struct yutani_msg_key_event * ke = (void*)m->data;
|
||||
yutani_msg_t * m_ = yutani_msg_build_key_event(0, &ke->event, &ke->state);
|
||||
int result = yutani_msg_send(y, m_);
|
||||
free(m_);
|
||||
}
|
||||
break;
|
||||
case YUTANI_MSG_WINDOW_MOUSE_EVENT:
|
||||
{
|
||||
struct yutani_msg_window_mouse_event * me = (void*)m->data;
|
||||
mouse_device_packet_t packet;
|
||||
|
||||
packet.buttons = me->buttons;
|
||||
packet.x_difference = me->new_x;
|
||||
packet.y_difference = me->new_y;
|
||||
|
||||
yutani_msg_t * m_ = yutani_msg_build_mouse_event(0, &packet, YUTANI_MOUSE_EVENT_TYPE_ABSOLUTE);
|
||||
int result = yutani_msg_send(y, m_);
|
||||
free(m_);
|
||||
}
|
||||
break;
|
||||
case YUTANI_MSG_RESIZE_OFFER:
|
||||
{
|
||||
struct yutani_msg_window_resize * wr = (void*)m->data;
|
||||
TRACE("Resize request from host compositor for size %dx%d", wr->width, wr->height);
|
||||
yutani_window_resize_accept(yg->host_context, yg->host_window, wr->width, wr->height);
|
||||
yg->resize_on_next = 1;
|
||||
}
|
||||
break;
|
||||
case YUTANI_MSG_SESSION_END:
|
||||
TRACE("Host session ended. Should exit.");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
free(m);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Mouse input thread
|
||||
*
|
||||
* Reads the kernel mouse device and converts
|
||||
* mouse clicks and movements into event objects
|
||||
* to send to the core compositor.
|
||||
*/
|
||||
static uint32_t last_mouse_buttons = 0;
|
||||
void * mouse_input(void * garbage) {
|
||||
int mfd = open("/dev/mouse", O_RDONLY);
|
||||
|
||||
yutani_t * y = yutani_init();
|
||||
mouse_device_packet_t packet;
|
||||
|
||||
while (1) {
|
||||
int r = read(mfd, (char *)&packet, sizeof(mouse_device_packet_t));
|
||||
if (r > 0) {
|
||||
last_mouse_buttons = packet.buttons;
|
||||
yutani_msg_t * m = yutani_msg_build_mouse_event(0, &packet, YUTANI_MOUSE_EVENT_TYPE_RELATIVE);
|
||||
int result = yutani_msg_send(y, m);
|
||||
free(m);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void * mouse_input_abs(void * garbage) {
|
||||
int mfd = open("/dev/absmouse", O_RDONLY);
|
||||
|
||||
if (mfd == -1) return 0;
|
||||
|
||||
yutani_t * y = yutani_init();
|
||||
mouse_device_packet_t packet;
|
||||
|
||||
while (1) {
|
||||
int r = read(mfd, (char *)&packet, sizeof(mouse_device_packet_t));
|
||||
if (r > 0) {
|
||||
packet.buttons = last_mouse_buttons & 0xF;
|
||||
yutani_msg_t * m = yutani_msg_build_mouse_event(0, &packet, YUTANI_MOUSE_EVENT_TYPE_ABSOLUTE);
|
||||
int result = yutani_msg_send(y, m);
|
||||
free(m);
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifndef syscall_fswait
|
||||
/* TODO: This isn't in our newlib syscall bindings yet. */
|
||||
DEFN_SYSCALL2(fswait,59,int,int*);
|
||||
#endif
|
||||
|
||||
void * timer_tick(void * _server) {
|
||||
(void)_server;
|
||||
@ -589,32 +493,6 @@ void * timer_tick(void * _server) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Keyboard input thread
|
||||
*
|
||||
* Reads the kernel keyboard device and converts
|
||||
* key presses into event objects to send to the
|
||||
* core compositor.
|
||||
*/
|
||||
void * keyboard_input(void * garbage) {
|
||||
int kfd = open("/dev/kbd", O_RDONLY);
|
||||
|
||||
yutani_t * y = yutani_init();
|
||||
key_event_t event;
|
||||
key_event_state_t state = {0};
|
||||
|
||||
while (1) {
|
||||
char buf[1];
|
||||
int r = read(kfd, buf, 1);
|
||||
if (r > 0) {
|
||||
kbd_scancode(&state, buf[0], &event);
|
||||
yutani_msg_t * m = yutani_msg_build_key_event(0, &event, &state);
|
||||
int result = yutani_msg_send(y, m);
|
||||
free(m);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#define FONT_PATH "/usr/share/fonts/"
|
||||
#define FONT(a,b) {a, FONT_PATH b}
|
||||
|
||||
@ -2109,6 +1987,7 @@ int main(int argc, char * argv[]) {
|
||||
yg->host_context = yutani_init();
|
||||
yg->host_window = yutani_window_create(yg->host_context, yutani_options.nest_width, yutani_options.nest_height);
|
||||
yutani_window_move(yg->host_context, yg->host_window, 50, 50);
|
||||
yutani_window_advertise_icon(yg->host_context, yg->host_window, "Compositor", "compositor");
|
||||
yg->backend_ctx = init_graphics_yutani_double_buffer(yg->host_window);
|
||||
} else {
|
||||
_static_yg = yg;
|
||||
@ -2178,23 +2057,9 @@ int main(int argc, char * argv[]) {
|
||||
|
||||
yutani_cairo_init(yg);
|
||||
|
||||
pthread_t mouse_thread;
|
||||
pthread_t absmouse_thread;
|
||||
pthread_t keyboard_thread;
|
||||
pthread_t render_thread;
|
||||
pthread_t nested_thread;
|
||||
pthread_t timer_thread;
|
||||
|
||||
if (yutani_options.nested) {
|
||||
/* Nested Yutani-Yutani mouse+keyboard */
|
||||
pthread_create(&nested_thread, NULL, nested_input, yg);
|
||||
} else {
|
||||
/* Toaru mouse+keyboard driver */
|
||||
pthread_create(&mouse_thread, NULL, mouse_input, NULL);
|
||||
pthread_create(&absmouse_thread, NULL, mouse_input_abs, NULL);
|
||||
pthread_create(&keyboard_thread, NULL, keyboard_input, NULL);
|
||||
}
|
||||
|
||||
pthread_create(&render_thread, NULL, redraw, yg);
|
||||
pthread_create(&timer_thread, NULL, timer_tick, yg);
|
||||
|
||||
@ -2208,7 +2073,108 @@ int main(int argc, char * argv[]) {
|
||||
}
|
||||
}
|
||||
|
||||
int fds[4], mfd, kfd, amfd;
|
||||
mouse_device_packet_t packet;
|
||||
key_event_t event;
|
||||
key_event_state_t state = {0};
|
||||
uint32_t last_mouse_buttons = 0;
|
||||
|
||||
fds[0] = fileno(server);
|
||||
|
||||
if (yutani_options.nested) {
|
||||
fds[1] = fileno(yg->host_context->sock);
|
||||
} else {
|
||||
mfd = open("/dev/mouse", O_RDONLY);
|
||||
kfd = open("/dev/kbd", O_RDONLY);
|
||||
amfd = open("/dev/absmouse", O_RDONLY);
|
||||
|
||||
fds[1] = mfd;
|
||||
fds[2] = kfd;
|
||||
fds[3] = amfd;
|
||||
}
|
||||
|
||||
while (1) {
|
||||
if (yutani_options.nested) {
|
||||
int index = syscall_fswait(2, fds);
|
||||
|
||||
if (index == 1) {
|
||||
yutani_msg_t * m = yutani_poll(yg->host_context);
|
||||
if (m) {
|
||||
switch (m->type) {
|
||||
case YUTANI_MSG_KEY_EVENT:
|
||||
{
|
||||
struct yutani_msg_key_event * ke = (void*)m->data;
|
||||
yutani_msg_t * m_ = yutani_msg_build_key_event(0, &ke->event, &ke->state);
|
||||
handle_key_event(yg, (struct yutani_msg_key_event *)m_->data);
|
||||
free(m_);
|
||||
}
|
||||
break;
|
||||
case YUTANI_MSG_WINDOW_MOUSE_EVENT:
|
||||
{
|
||||
struct yutani_msg_window_mouse_event * me = (void*)m->data;
|
||||
mouse_device_packet_t packet;
|
||||
|
||||
packet.buttons = me->buttons;
|
||||
packet.x_difference = me->new_x;
|
||||
packet.y_difference = me->new_y;
|
||||
|
||||
yutani_msg_t * m_ = yutani_msg_build_mouse_event(0, &packet, YUTANI_MOUSE_EVENT_TYPE_ABSOLUTE);
|
||||
handle_mouse_event(yg, (struct yutani_msg_mouse_event *)m_->data);
|
||||
free(m_);
|
||||
}
|
||||
break;
|
||||
case YUTANI_MSG_RESIZE_OFFER:
|
||||
{
|
||||
struct yutani_msg_window_resize * wr = (void*)m->data;
|
||||
TRACE("Resize request from host compositor for size %dx%d", wr->width, wr->height);
|
||||
yutani_window_resize_accept(yg->host_context, yg->host_window, wr->width, wr->height);
|
||||
yg->resize_on_next = 1;
|
||||
}
|
||||
break;
|
||||
case YUTANI_MSG_SESSION_END:
|
||||
TRACE("Host session ended. Should exit.");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
free(m);
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
int index = syscall_fswait(amfd == -1 ? 3 : 4, fds);
|
||||
|
||||
if (index == 2) {
|
||||
char buf[1];
|
||||
int r = read(kfd, buf, 1);
|
||||
if (r > 0) {
|
||||
kbd_scancode(&state, buf[0], &event);
|
||||
yutani_msg_t * m = yutani_msg_build_key_event(0, &event, &state);
|
||||
handle_key_event(yg, (struct yutani_msg_key_event *)m->data);
|
||||
free(m);
|
||||
}
|
||||
continue;
|
||||
} else if (index == 1) {
|
||||
int r = read(mfd, (char *)&packet, sizeof(mouse_device_packet_t));
|
||||
if (r > 0) {
|
||||
last_mouse_buttons = packet.buttons;
|
||||
yutani_msg_t * m = yutani_msg_build_mouse_event(0, &packet, YUTANI_MOUSE_EVENT_TYPE_RELATIVE);
|
||||
handle_mouse_event(yg, (struct yutani_msg_mouse_event *)m->data);
|
||||
free(m);
|
||||
}
|
||||
continue;
|
||||
} else if (index == 3) {
|
||||
int r = read(amfd, (char *)&packet, sizeof(mouse_device_packet_t));
|
||||
if (r > 0) {
|
||||
packet.buttons = last_mouse_buttons & 0xF;
|
||||
yutani_msg_t * m = yutani_msg_build_mouse_event(0, &packet, YUTANI_MOUSE_EVENT_TYPE_ABSOLUTE);
|
||||
handle_mouse_event(yg, (struct yutani_msg_mouse_event *)m->data);
|
||||
free(m);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
pex_packet_t * p = calloc(PACKET_SIZE, 1);
|
||||
pex_listen(server, p);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user