diff --git a/src/backend/sdl.c b/src/backend/sdl.c index 221a7d6..db28601 100644 --- a/src/backend/sdl.c +++ b/src/backend/sdl.c @@ -1,5 +1,6 @@ #include "../backend.h" #include "../ctxt/theme.h" +#include "../util.h" #include "../util/region.h" #include "../concurrent/msgq.h" #include "../concurrent/msg.h" @@ -145,25 +146,42 @@ struct ax_font_h { TTF_Font* font; }; -static void load_fonts( - struct ax_backend* bac, - struct font_list* fl) +static int load_font( + struct rgn* rgn, const char* path, size_t size, + struct ax_font_h** out_fh, const char** out_err) { + struct ax_font_h* fh = ralloc_typed(rgn, struct ax_font_h, 1); + if ((fh->font = TTF_OpenFont(path, size)) == NULL) { + *out_err = TTF_GetError(); + return 1; + } + *out_fh = fh; + return 0; +} + +static void load_fonts(struct ax_backend* bac, struct font_list* fl) +{ + int rv = 0; + const char* err; + for (; fl != NULL; fl = fl->next) { struct ax_theme* thm = fl->thm; - struct msgq* cb_mq = fl->cb_mq; - const char* path = thm->font_path[fl->cat]; - size_t size = thm->font_size[fl->cat]; - - struct ax_font_h* handle = ralloc_typed(bac->rgn, struct ax_font_h, 1); - handle->font = TTF_OpenFont(path, size); - thm->font_handle[fl->cat] = handle; - - if (ax__theme_is_loaded(thm)) { + struct ax_font_h* fh; + if ((rv = load_font(bac->rgn, + thm->font_path[fl->cat], + thm->font_size[fl->cat], + &fh, &err)) != 0) { + goto fail; + } + bool is_loaded = ax__theme_set_font_handle(thm, fl->cat, fh); + if (is_loaded) { struct ax_msg_theme_loaded* m = - msgq_begin_send_typed(cb_mq, ax_msg_theme_loaded); + msgq_begin_send_typed(fl->cb_mq, ax_msg_theme_loaded); m->theme = thm; - msgq_end_send(cb_mq); + msgq_end_send(fl->cb_mq); } } + +fail: + ASSERT(rv == 0, "error loading font: %s", err); } diff --git a/src/ctxt/theme.c b/src/ctxt/theme.c index 294217a..e7f81c6 100644 --- a/src/ctxt/theme.c +++ b/src/ctxt/theme.c @@ -12,6 +12,10 @@ static const char* default_font_path(struct rgn* rgn) return "/usr/share/fonts/liberation/LiberationSans-Regular.ttf"; } +/* ----------------------------------------------------------------------------- + * Theme builder functions + * -------------------------------------------------------------------------- */ + void ax__theme_builder_init(struct ax_theme_builder* thmb, struct rgn* rgn) { thmb->rgn = rgn; @@ -83,7 +87,6 @@ void ax__theme_builder_finish( if (thmb->err != NULL) { thm->err = rstrdup(dst_rgn, thmb->err); - return; } const char* dflt_font_path = (thmb->dflt_font_path == NULL) ? @@ -97,6 +100,53 @@ void ax__theme_builder_finish( dflt_font_path : rstrdup(dst_rgn, thm->font_path[i]); } + + pthread_mutex_init(&thm->handles_mx, NULL); + rgn_pin(dst_rgn, thm, (void*) pthread_mutex_destroy); +} + +/* ----------------------------------------------------------------------------- + * Theme functions + * -------------------------------------------------------------------------- */ + +static inline bool is_loaded(struct ax_theme* thm) +{ + for (size_t i = 0; i < AX_FONT__COUNT; i++) { + if (thm->font_handle[i] == NULL) { + return false; + } + } + return true; +} + +struct ax_font_h* ax__theme_font_handle( + struct ax_theme* thm, + enum ax_font_cat i) +{ + pthread_mutex_lock(&thm->handles_mx); + struct ax_font_h* h = thm->font_handle[i]; + pthread_mutex_unlock(&thm->handles_mx); + return h; +} + +bool ax__theme_is_loaded(struct ax_theme* thm) +{ + pthread_mutex_lock(&thm->handles_mx); + bool l = is_loaded(thm); + pthread_mutex_unlock(&thm->handles_mx); + return l; +} + +bool ax__theme_set_font_handle( + struct ax_theme* thm, + enum ax_font_cat i, + struct ax_font_h* h) +{ + pthread_mutex_lock(&thm->handles_mx); + thm->font_handle[i] = h; + bool l = is_loaded(thm); + pthread_mutex_unlock(&thm->handles_mx); + return l; } void ax__theme_request_load( @@ -133,6 +183,7 @@ int ax__string_to_font_cat(const char* str, enum ax_font_cat* out_cat) return 0; } +/* void ax__debug_theme(struct ax_theme* thm) { printf("=========\nTHEME INFO:\n"); @@ -152,3 +203,4 @@ void ax__debug_theme(struct ax_theme* thm) str, thm->font_path[i], thm->font_size[i]); } } +*/ diff --git a/src/ctxt/theme.h b/src/ctxt/theme.h index 66de4e1..3f7a5db 100644 --- a/src/ctxt/theme.h +++ b/src/ctxt/theme.h @@ -3,6 +3,7 @@ #include #include #include +#include struct rgn; struct msgq; @@ -42,6 +43,7 @@ struct ax_theme { size_t font_size[AX_FONT__COUNT]; const char* font_path[AX_FONT__COUNT]; struct ax_font_h* font_handle[AX_FONT__COUNT]; + pthread_mutex_t handles_mx; }; struct ax_theme_builder { @@ -74,22 +76,6 @@ void ax__theme_builder_finish( struct rgn* dst_rgn, struct ax_theme** out_thm); -void ax__theme_request_load( - struct ax_theme* thm, - struct msgq* req_mq, - struct msgq* res_mq); - -static inline bool ax__theme_is_loaded( - struct ax_theme* thm) -{ - for (size_t i = 0; i < AX_FONT__COUNT; i++) { - if (thm->font_handle[i] == NULL) { - return false; - } - } - return true; -} - static inline int64_t ax__theme_color( struct ax_theme* thm, enum ax_color_cat i) @@ -108,5 +94,23 @@ static inline const char* ax__theme_font( return thm->font_path[i]; } +struct ax_font_h* ax__theme_font_handle( + struct ax_theme* thm, + enum ax_font_cat i); +bool ax__theme_is_loaded( + struct ax_theme* thm); + +bool ax__theme_set_font_handle( // returns `true` if the font is now loaded + struct ax_theme* thm, + enum ax_font_cat i, + struct ax_font_h* h); + +void ax__theme_request_load( + struct ax_theme* thm, + struct msgq* req_mq, + struct msgq* res_mq); + +/* void ax__debug_theme(struct ax_theme* thm); +*/