/* A complete CPU-rendered window. Build instructions: docs/getting-started.md. */ #include #include #include struct app { bool running; bool failed; bool smoke_test; }; static void quit(void *ud) { ((struct app *)ud)->running = false; } static void lost(void *ud) { struct app *app = ud; app->failed = true; app->running = false; } static void close_window(struct yasl_surface *surface, void *ud) { (void)surface; quit(ud); } static void configure(struct yasl_surface *surface, struct yasl_geometry geometry, void *ud) { (void)geometry; (void)ud; yasl_surface_schedule_redraw(surface); } static void draw(struct yasl_surface *surface, struct yasl_frame *frame, void *ud) { struct app *app = ud; size_t count = (size_t)frame->target.size.x * frame->target.size.y; for (size_t i = 0; i < count; i++) frame->target.pixels[i] = 0xff306090; /* Opaque premultiplied ARGB. */ struct yasl_damage_list damage = {.n = -1}; if (!yasl_surface_present(surface, &frame->target, &damage)) { fprintf(stderr, "Could not present the draw target\n"); app->failed = true; app->running = false; } if (app->smoke_test) app->running = false; } int main(int argc, char **argv) { struct app app = {.running = true}; if (argc == 2 && strcmp(argv[1], "--smoke-test") == 0) app.smoke_test = true; else if (argc != 1) { fprintf(stderr, "Usage: %s [--smoke-test]\n", argv[0]); return 1; } struct yasl_display_cbs display_callbacks = {.quit = quit, .lost = lost}; struct yasl_display_spec display_spec = { .app_id = "org.example.hello", .cbs = &display_callbacks, .ud = &app, }; struct yasl_display *display = yasl_display_open(NULL, &display_spec); if (!display) { perror("yasl_display_open"); return 1; } struct yasl_window_cbs callbacks = { .draw = draw, .configure = configure, .close = close_window, }; struct yasl_window_spec spec = { .title = "Hello YASL", .size = {640, 480}, .cbs = &callbacks, .ud = &app, }; struct yasl_surface *surface = yasl_surface_create_toplevel(display, &spec); if (!surface) { perror("yasl_surface_create_toplevel"); yasl_display_close(display); return 1; } yasl_surface_schedule_redraw(surface); while (app.running) { if (yasl_display_dispatch(display, -1) < 0) { perror("yasl_display_dispatch"); app.failed = true; break; } /* Drain even unused input so queued events do not cause a busy loop. */ struct yasl_input_event event; while (yasl_surface_input_poll(surface, &event)) {} if (app.running) yasl_display_flush(display); } yasl_surface_destroy(surface); yasl_display_close(display); return app.failed ? 1 : 0; }