Skip to content

Commit

Permalink
Refine event handling
Browse files Browse the repository at this point in the history
This commit adds a member function for event handling to the backend
interface, replacing the previous file-based system that relies on
poll(2). The new design addresses issues created by backends like SDL,
which do not expose underlying file descriptors. Integrating the fbdev
backend into the updated interface remains to be completed.

Close sysprog21#4
  • Loading branch information
alanjian85 committed Nov 19, 2024
1 parent 980bd4c commit 607ce07
Show file tree
Hide file tree
Showing 9 changed files with 66 additions and 216 deletions.
1 change: 0 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ libtwin.a_cflags-y :=

libtwin.a_files-y = \
src/box.c \
src/file.c \
src/poly.c \
src/toplevel.c \
src/button.c \
Expand Down
2 changes: 1 addition & 1 deletion apps/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ int main(void)
20);
#endif

twin_dispatch();
twin_dispatch(tx);

return 0;
}
13 changes: 0 additions & 13 deletions backend/linux_input.c
Original file line number Diff line number Diff line change
Expand Up @@ -144,11 +144,6 @@ static void *twin_linux_evdev_thread(void *arg)
return NULL;
}

static bool dummy(int file, twin_file_op_t ops, void *closure)
{
return true;
}

void *twin_linux_input_create(twin_screen_t *screen)
{
/* Create object for handling Linux input system */
Expand All @@ -162,14 +157,6 @@ void *twin_linux_input_create(twin_screen_t *screen)
tm->x = screen->width / 2;
tm->y = screen->height / 2;

#if 1
/* FIXME: Need to fix the unexpected termination of the program.
* Hooking a dummy function here is only a hack*/

/* Set file handler for reading input device file */
twin_set_file(dummy, tm->fd, TWIN_READ, tm);
#endif

/* Start event handling thread */
if (pthread_create(&tm->evdev_thread, NULL, twin_linux_evdev_thread, tm)) {
log_error("Failed to create evdev thread");
Expand Down
99 changes: 48 additions & 51 deletions backend/sdl.c
Original file line number Diff line number Diff line change
Expand Up @@ -72,55 +72,6 @@ static void twin_sdl_damage(twin_screen_t *screen, twin_sdl_t *tx)
twin_screen_damage(screen, 0, 0, width, height);
}

static bool twin_sdl_read_events(int file maybe_unused,
twin_file_op_t ops maybe_unused,
void *closure)
{
twin_screen_t *screen = SCREEN(closure);
twin_sdl_t *tx = PRIV(closure);

SDL_Event ev;
while (SDL_PollEvent(&ev)) {
twin_event_t tev;
switch (ev.type) {
case SDL_WINDOWEVENT:
if (ev.window.event == SDL_WINDOWEVENT_EXPOSED ||
ev.window.event == SDL_WINDOWEVENT_SHOWN) {
twin_sdl_damage(screen, tx);
}
break;
case SDL_QUIT:
_twin_sdl_destroy(screen, tx);
return false;
case SDL_MOUSEBUTTONDOWN:
case SDL_MOUSEBUTTONUP:
tev.u.pointer.screen_x = ev.button.x;
tev.u.pointer.screen_y = ev.button.y;
tev.u.pointer.button =
((ev.button.state >> 8) | (1 << (ev.button.button - 1)));
tev.kind = ((ev.type == SDL_MOUSEBUTTONDOWN) ? TwinEventButtonDown
: TwinEventButtonUp);
twin_screen_dispatch(screen, &tev);
break;
case SDL_KEYDOWN:
case SDL_KEYUP:
tev.u.key.key = ev.key.keysym.sym;
tev.kind = ((ev.key.type == SDL_KEYDOWN) ? TwinEventKeyDown
: TwinEventKeyUp);
twin_screen_dispatch(screen, &tev);
break;
case SDL_MOUSEMOTION:
tev.u.pointer.screen_x = ev.motion.x;
tev.u.pointer.screen_y = ev.motion.y;
tev.kind = TwinEventMotion;
tev.u.pointer.button = ev.motion.state;
twin_screen_dispatch(screen, &tev);
break;
}
}
return true;
}

static bool twin_sdl_work(void *closure)
{
twin_screen_t *screen = SCREEN(closure);
Expand Down Expand Up @@ -174,8 +125,6 @@ twin_context_t *twin_sdl_init(int width, int height)
ctx->screen = twin_screen_create(width, height, _twin_sdl_put_begin,
_twin_sdl_put_span, ctx);

twin_set_file(twin_sdl_read_events, 0, TWIN_READ, ctx);

twin_set_work(twin_sdl_work, TWIN_WORK_REDISPLAY, ctx);

return ctx;
Expand All @@ -195,6 +144,53 @@ static void twin_sdl_configure(twin_context_t *ctx)
twin_screen_resize(ctx->screen, width, height);
}

static bool twin_sdl_poll(twin_context_t *ctx)
{
twin_screen_t *screen = SCREEN(ctx);
twin_sdl_t *tx = PRIV(ctx);

SDL_Event ev;
while (SDL_PollEvent(&ev)) {
twin_event_t tev;
switch (ev.type) {
case SDL_WINDOWEVENT:
if (ev.window.event == SDL_WINDOWEVENT_EXPOSED ||
ev.window.event == SDL_WINDOWEVENT_SHOWN) {
twin_sdl_damage(screen, tx);
}
break;
case SDL_QUIT:
_twin_sdl_destroy(screen, tx);
return false;
case SDL_MOUSEBUTTONDOWN:
case SDL_MOUSEBUTTONUP:
tev.u.pointer.screen_x = ev.button.x;
tev.u.pointer.screen_y = ev.button.y;
tev.u.pointer.button =
((ev.button.state >> 8) | (1 << (ev.button.button - 1)));
tev.kind = ((ev.type == SDL_MOUSEBUTTONDOWN) ? TwinEventButtonDown
: TwinEventButtonUp);
twin_screen_dispatch(screen, &tev);
break;
case SDL_KEYDOWN:
case SDL_KEYUP:
tev.u.key.key = ev.key.keysym.sym;
tev.kind = ((ev.key.type == SDL_KEYDOWN) ? TwinEventKeyDown
: TwinEventKeyUp);
twin_screen_dispatch(screen, &tev);
break;
case SDL_MOUSEMOTION:
tev.u.pointer.screen_x = ev.motion.x;
tev.u.pointer.screen_y = ev.motion.y;
tev.kind = TwinEventMotion;
tev.u.pointer.button = ev.motion.state;
twin_screen_dispatch(screen, &tev);
break;
}
}
return true;
}

static void twin_sdl_exit(twin_context_t *ctx)
{
if (!ctx)
Expand All @@ -209,5 +205,6 @@ static void twin_sdl_exit(twin_context_t *ctx)
const twin_backend_t g_twin_backend = {
.init = twin_sdl_init,
.configure = twin_sdl_configure,
.poll = twin_sdl_poll,
.exit = twin_sdl_exit,
};
28 changes: 6 additions & 22 deletions include/twin.h
Original file line number Diff line number Diff line change
Expand Up @@ -455,15 +455,10 @@ typedef twin_time_t (*twin_timeout_proc_t)(twin_time_t now, void *closure);

typedef bool (*twin_work_proc_t)(void *closure);

typedef enum _twin_file_op { TWIN_READ = 1, TWIN_WRITE = 2 } twin_file_op_t;

typedef bool (*twin_file_proc_t)(int file, twin_file_op_t ops, void *closure);

#define twin_time_compare(a, op, b) (((a) - (b)) op 0)

typedef struct _twin_timeout twin_timeout_t;
typedef struct _twin_work twin_work_t;
typedef struct _twin_file twin_file_t;

/*
* Widgets
Expand Down Expand Up @@ -585,6 +580,11 @@ struct _twin_scroll {
twin_widget_t widget;
};

typedef struct _twin_context {
twin_screen_t *screen;
void *priv;
} twin_context_t;

/*
* box.c
*/
Expand Down Expand Up @@ -619,7 +619,7 @@ twin_pixmap_t *twin_make_cursor(int *hx, int *hy);
* dispatch.c
*/

void twin_dispatch(void);
void twin_dispatch(twin_context_t *ctx);

/*
* draw.c
Expand Down Expand Up @@ -654,17 +654,6 @@ void twin_premultiply_alpha(twin_pixmap_t *px);

void twin_event_enqueue(const twin_event_t *event);

/*
* file.c
*/

twin_file_t *twin_set_file(twin_file_proc_t file_proc,
int file,
twin_file_op_t ops,
void *closure);

void twin_clear_file(twin_file_t *file);

/*
* fixed.c
*/
Expand Down Expand Up @@ -1170,11 +1159,6 @@ void twin_clear_work(twin_work_t *work);
* backend
*/

typedef struct _twin_context {
twin_screen_t *screen;
void *priv;
} twin_context_t;

twin_context_t *twin_create(int width, int height);

void twin_destroy(twin_context_t *ctx);
Expand Down
10 changes: 0 additions & 10 deletions include/twin_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -472,14 +472,6 @@ struct _twin_work {
void *closure;
};

struct _twin_file {
twin_queue_t queue;
int file;
twin_file_op_t ops;
twin_file_proc_t proc;
void *closure;
};

typedef enum _twin_order {
TWIN_BEFORE = -1,
TWIN_AT = 0,
Expand All @@ -504,8 +496,6 @@ twin_queue_t *_twin_queue_set_order(twin_queue_t **head);

void _twin_queue_review_order(twin_queue_t *first);

int _twin_run_file(twin_time_t delay);

void _twin_run_timeout(void);

twin_time_t _twin_timeout_delay(void);
Expand Down
11 changes: 9 additions & 2 deletions src/dispatch.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,21 @@
* All rights reserved.
*/

#include <unistd.h>

#include "twin_backend.h"
#include "twin_private.h"

void twin_dispatch(void)
extern twin_backend_t g_twin_backend;

void twin_dispatch(twin_context_t *ctx)
{
for (;;) {
_twin_run_timeout();
_twin_run_work();
if (!_twin_run_file(_twin_timeout_delay()))
if (g_twin_backend.poll && !g_twin_backend.poll(ctx)) {
usleep(_twin_timeout_delay() * 1000);
break;
}
}
}
Loading

0 comments on commit 607ce07

Please sign in to comment.