diff --git a/src/backend/sdl.c b/src/backend/sdl.c index 2bf9bc8..b9ed7ca 100644 --- a/src/backend/sdl.c +++ b/src/backend/sdl.c @@ -1,5 +1,6 @@ #include "../backend.h" #include "../ctxt/theme.h" +#include "../ctxt/window.h" #include "../util.h" #include "../util/region.h" #include "../concurrent/msgq.h" @@ -12,6 +13,8 @@ * Backend type * -------------------------------------------------------------------------- */ +struct window_list; + const char* ax__backend_impl_name = "SDL"; size_t ax__backend_desired_region_size = MEDIUM; @@ -19,6 +22,7 @@ struct ax_backend { struct rgn* rgn; struct msgq* inbox; bool shutdown; + struct window_list* windows; }; /* ----------------------------------------------------------------------------- @@ -48,6 +52,7 @@ int ax__backend_new( bac->rgn = init_rgn; bac->inbox = msgq_new(init_rgn); bac->shutdown = false; + bac->windows = NULL; if (out_bac != NULL) { *out_bac = bac; @@ -82,7 +87,7 @@ bool ax__backend_is_shutdown(struct ax_backend* bac) void ax__backend_wait_for_event(struct ax_backend* bac) { (void) bac; - usleep(1000 * 1000); + usleep(1000 * 100); } /* ----------------------------------------------------------------------------- @@ -95,21 +100,32 @@ struct font_list { size_t cat; }; -static void load_fonts( - struct ax_backend* bac, struct font_list* fonts); +struct window_args_list { + struct window_args_list* next; + struct ax_window* win; + const char* title; + uint32_t width, height; +}; + +static void load_fonts(struct ax_backend* bac, struct font_list* fl); +static void make_windows(struct ax_backend* bac, struct window_args_list* wl); +static void render_windows(struct window_list* wl); void ax__backend_step(struct ax_backend* bac) { struct rgn tmp_rgn; rgn_init(&tmp_rgn, SMALL); + struct font_list* fonts = NULL; + struct window_args_list* windows = NULL; + size_t nmsg = 0; msgq_begin_recv(bac->inbox); - MSGQ_RECV_ALL(bac->inbox) { ON(ax_msg_shutdown, { + nmsg++; (void) m; bac->shutdown = true; break; @@ -117,6 +133,7 @@ void ax__backend_step(struct ax_backend* bac) ON(ax_msg_load_font, { + nmsg++; struct font_list* l = ralloc_typed(&tmp_rgn, struct font_list, 1); l->next = fonts; @@ -126,16 +143,33 @@ void ax__backend_step(struct ax_backend* bac) break; }); + ON(ax_msg_make_window, + { + nmsg++; + struct window_args_list* l = + ralloc_typed(&tmp_rgn, struct window_args_list, 1); + l->next = windows; + l->win = m.dst_win; + l->title = rstrdup(&tmp_rgn, m.title); + l->width = m.width; + l->height = m.height; + windows = l; + break; + }); + default: + nmsg++; printf("Got a weird message: `%s'\n", ax__msg_name(mqr__type)); break; } - msgq_end_recv(bac->inbox); load_fonts(bac, fonts); + make_windows(bac, windows); + render_windows(bac->windows); rgn_cleanup(&tmp_rgn); + // printf("ping. %zu message(s)\n", nmsg); } /* ----------------------------------------------------------------------------- @@ -180,3 +214,86 @@ static void load_fonts(struct ax_backend* bac, struct font_list* fl) fail: ASSERT(rv == 0, "error loading font: %s", err); } + +/* ----------------------------------------------------------------------------- + * Window management + * -------------------------------------------------------------------------- */ + +struct window_list { + struct window_list* next; + struct ax_window* win; + struct window_handle* handle; +}; + +struct window_handle { + SDL_Window* win; + SDL_Renderer* rnd; +}; + +static void cleanup_window_handle(struct window_handle*); + +static int new_window_handle( + struct rgn* rgn, + struct window_args_list* args, + struct window_handle** out_wh, + const char** out_err) +{ + struct window_handle* wh = ralloc_typed(rgn, struct window_handle, 1); + wh->win = NULL; + wh->rnd = NULL; + rgn_pin(rgn, wh, (void*) cleanup_window_handle); + + int rv; + if ((rv = SDL_CreateWindowAndRenderer((int) args->width, + (int) args->height, + SDL_WINDOW_SHOWN, + &wh->win, &wh->rnd)) != 0) { + *out_err = SDL_GetError(); + return rv; + } + + SDL_SetWindowTitle(wh->win, args->title); + + *out_wh = wh; + return 0; +} + +static void cleanup_window_handle(struct window_handle* wh) +{ + SDL_DestroyRenderer(wh->rnd); + SDL_DestroyWindow(wh->win); +} + +static void make_windows(struct ax_backend* bac, struct window_args_list* args) +{ + int rv = 0; + const char* err; + struct window_handle* wh; + struct window_list* wl; + + for (; args != NULL; args = args->next) { + if ((rv = new_window_handle(bac->rgn, args, &wh, &err)) != 0) { + goto fail; + } + + wl = ralloc_typed(bac->rgn, struct window_list, 1); + wl->win = args->win; + wl->handle = wh; + wl->next = bac->windows; + bac->windows = wl; + } + +fail: + ASSERT(rv == 0, "error: %s", SDL_GetError()); +} + +static void render_windows(struct window_list* wl) +{ + for (; wl != NULL; wl = wl->next) { + // SDL_Window* sdl_win = wl->handle->win; + SDL_Renderer* r = wl->handle->rnd; + SDL_SetRenderDrawColor(r, 255, 255, 255, 255); + SDL_RenderClear(r); + SDL_RenderPresent(r); + } +} diff --git a/src/ctxt/window.c b/src/ctxt/window.c index 03a6d8d..ea273c3 100644 --- a/src/ctxt/window.c +++ b/src/ctxt/window.c @@ -31,7 +31,6 @@ struct ax_window* ax__window_builder_finish( { struct ax_window* win = ralloc_typed(dst_rgn, struct ax_window, 1); - win->handle = NULL; pthread_mutex_init(&win->mx, NULL); rgn_pin(dst_rgn, &win->mx, (void*) pthread_mutex_destroy); diff --git a/src/ctxt/window.h b/src/ctxt/window.h index 8697bda..e116405 100644 --- a/src/ctxt/window.h +++ b/src/ctxt/window.h @@ -16,7 +16,6 @@ enum ax_window_flags { }; struct ax_window { - struct ax_window_h* handle; pthread_mutex_t mx; };