Add a rudimentary API for providing timer ticks through Yutani

This commit is contained in:
Kevin Lange 2017-01-01 20:39:18 +09:00
parent 5ef927c175
commit 3a924099fd
6 changed files with 124 additions and 17 deletions

View File

@ -576,6 +576,18 @@ void * mouse_input_abs(void * garbage) {
}
}
void * timer_tick(void * _server) {
(void)_server;
//yutani_globals_t * yg = _server;
yutani_t * y = yutani_init();
yutani_msg_t * m = yutani_msg_build_timer_tick();
while (1) {
usleep(50000); /* XXX timer precision */
yutani_msg_send(y, m);
}
}
/**
* Keyboard input thread
*
@ -2155,6 +2167,7 @@ int main(int argc, char * argv[]) {
yg->mid_zs = list_create();
yg->window_subscribers = list_create();
yg->timer_subscribers = list_create();
yutani_cairo_init(yg);
@ -2163,6 +2176,7 @@ int main(int argc, char * argv[]) {
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 */
@ -2175,6 +2189,7 @@ int main(int argc, char * argv[]) {
}
pthread_create(&render_thread, NULL, redraw, yg);
pthread_create(&timer_thread, NULL, timer_tick, yg);
if (!fork()) {
if (argx < argc) {
@ -2499,6 +2514,38 @@ int main(int argc, char * argv[]) {
}
}
break;
case YUTANI_MSG_TIMER_REQUEST:
{
struct yutani_msg_timer_request * tr = (void *)m->data;
/* TODO: precision */
if (tr->flags & 1) {
/* Unsubscribe */
node_t * node = list_find(yg->timer_subscribers, (void*)p->source);
if (node) {
list_delete(yg->timer_subscribers, node);
}
} else {
/* Subscribe */
foreach(node, yg->timer_subscribers) {
if ((uint32_t)node->value == p->source) {
break;
}
}
list_insert(yg->timer_subscribers, (void*)p->source);
}
}
break;
case YUTANI_MSG_TIMER_TICK:
{
/* Send timer ticks to requesters */
yutani_msg_t * response = yutani_msg_build_timer_tick();
foreach(node, yg->timer_subscribers) {
uint32_t subscriber = (uint32_t)node->value;
pex_send(yg->server, subscriber, response->size, (char *)response);
}
free(response);
}
default:
{
TRACE("Unknown type: 0x%8x", m->type);

View File

@ -169,6 +169,9 @@ typedef struct {
int current_cursor;
int resize_on_next;
uint32_t timer_precison;
list_t * timer_subscribers;
} yutani_globals_t;
struct key_bind {

View File

@ -931,6 +931,8 @@ static void resize_finish(int xwidth, int xheight) {
}
int main (int argc, char ** argv) {
int tick = 0;
/* Connect to window server */
yctx = yutani_init();
@ -1024,8 +1026,12 @@ int main (int argc, char ** argv) {
signal(SIGINT, sig_int);
/* Start clock thread XXX need timeouts in yutani calls */
#if 0
pthread_t _clock_thread;
pthread_create(&_clock_thread, NULL, clock_thread, NULL);
#endif
yutani_timer_request(yctx, 0, 0);
/* Subscribe to window updates */
yutani_subscribe_windows(yctx);
@ -1080,6 +1086,16 @@ int main (int argc, char ** argv) {
resize_finish(wr->width, wr->height);
}
break;
case YUTANI_MSG_TIMER_TICK:
{
tick++;
if (tick == 10) {
waitpid(-1, NULL, WNOHANG);
update_volume_level();
redraw();
tick = 0;
}
}
default:
break;
}

View File

@ -49,6 +49,7 @@
#include "gui/terminal/lib/termemu.h"
#define USE_BELL 0
#define CURSOR_BLINK_TIME 10
/* master and slave pty descriptors */
static int fd_master, fd_slave;
@ -1245,6 +1246,9 @@ void mouse_event(int button, int x, int y) {
}
void * handle_incoming(void * garbage) {
yutani_timer_request(yctx, 0, 0);
while (!exit_application) {
yutani_msg_t * m = yutani_poll(yctx);
if (m) {
@ -1335,6 +1339,16 @@ void * handle_incoming(void * garbage) {
}
}
break;
case YUTANI_MSG_TIMER_TICK:
{
timer_tick++;
if (timer_tick == CURSOR_BLINK_TIME) {
timer_tick = 0;
spin_lock(&display_lock);
flip_cursor();
spin_unlock(&display_lock);
}
}
default:
break;
}
@ -1344,20 +1358,6 @@ void * handle_incoming(void * garbage) {
pthread_exit(0);
}
void * blink_cursor(void * garbage) {
while (!exit_application) {
timer_tick++;
if (timer_tick == 3) {
timer_tick = 0;
spin_lock(&display_lock);
flip_cursor();
spin_unlock(&display_lock);
}
usleep(90000);
}
pthread_exit(0);
}
int main(int argc, char ** argv) {
_use_freetype = 1;
@ -1543,9 +1543,6 @@ int main(int argc, char ** argv) {
pthread_t handle_incoming_thread;
pthread_create(&handle_incoming_thread, NULL, handle_incoming, NULL);
pthread_t cursor_blink_thread;
pthread_create(&cursor_blink_thread, NULL, blink_cursor, NULL);
unsigned char buf[1024];
while (!exit_application) {
int r = read(fd_master, buf, 1024);

View File

@ -514,6 +514,34 @@ yutani_msg_t * yutani_msg_build_window_resize_start(yutani_wid_t wid, yutani_sca
return msg;
}
yutani_msg_t * yutani_msg_build_timer_request(uint32_t precision, uint32_t flags) {
size_t s = sizeof(struct yutani_message) + sizeof(struct yutani_msg_timer_request);
yutani_msg_t * msg = malloc(s);
msg->magic = YUTANI_MSG__MAGIC;
msg->type = YUTANI_MSG_TIMER_REQUEST;
msg->size = s;
struct yutani_msg_timer_request * tr = (void *)msg->data;
tr->precision = precision;
tr->flags = flags;
return msg;
}
yutani_msg_t * yutani_msg_build_timer_tick(void) {
size_t s = sizeof(struct yutani_message);
yutani_msg_t * msg = malloc(s);
msg->magic = YUTANI_MSG__MAGIC;
msg->type = YUTANI_MSG_TIMER_TICK;
msg->size = s;
return msg;
}
int yutani_msg_send(yutani_t * y, yutani_msg_t * msg) {
return pex_reply(y->sock, msg->size, (char *)msg);
}
@ -802,6 +830,11 @@ void yutani_window_resize_start(yutani_t * yctx, yutani_window_t * window, yutan
free(m);
}
void yutani_timer_request(yutani_t * yctx, uint32_t precision, uint32_t flags) {
yutani_msg_t * m = yutani_msg_build_timer_request(precision, flags);
int result = yutani_msg_send(yctx, m);
free(m);
}
gfx_context_t * init_graphics_yutani(yutani_window_t * window) {
gfx_context_t * out = malloc(sizeof(gfx_context_t));

View File

@ -179,6 +179,10 @@ struct yutani_msg_window_resize_start {
yutani_scale_direction_t direction;
};
struct yutani_msg_timer_request {
uint32_t precision;
uint32_t flags;
};
typedef struct yutani_window {
yutani_wid_t wid;
@ -239,6 +243,10 @@ typedef struct yutani_window {
#define YUTANI_MSG_GOODBYE 0x000000F0
/* Timing Event Requests */
#define YUTANI_MSG_TIMER_REQUEST 0x00000100
#define YUTANI_MSG_TIMER_TICK 0x00000101
/* Server responses */
#define YUTANI_MSG_WELCOME 0x00010001
#define YUTANI_MSG_WINDOW_INIT 0x00010002
@ -423,6 +431,8 @@ extern yutani_msg_t * yutani_msg_build_window_update_shape(yutani_wid_t wid, int
extern yutani_msg_t * yutani_msg_build_window_warp_mouse(yutani_wid_t wid, int32_t x, int32_t y);
extern yutani_msg_t * yutani_msg_build_window_show_mouse(yutani_wid_t wid, int32_t show_mouse);
extern yutani_msg_t * yutani_msg_build_window_resize_start(yutani_wid_t wid, yutani_scale_direction_t direction);
extern yutani_msg_t * yutani_msg_build_timer_request(uint32_t precision, uint32_t flags);
extern yutani_msg_t * yutani_msg_build_timer_tick(void);
extern int yutani_msg_send(yutani_t * y, yutani_msg_t * msg);
@ -452,6 +462,7 @@ extern void yutani_window_update_shape(yutani_t * yctx, yutani_window_t * window
extern void yutani_window_warp_mouse(yutani_t * yctx, yutani_window_t * window, int32_t x, int32_t y);
extern void yutani_window_show_mouse(yutani_t * yctx, yutani_window_t * window, int32_t show_mouse);
extern void yutani_window_resize_start(yutani_t * yctx, yutani_window_t * window, yutani_scale_direction_t direction);
extern void yutani_timer_request(yutani_t * yctx, uint32_t precision, uint32_t flags);
extern gfx_context_t * init_graphics_yutani(yutani_window_t * window);