// Just random stdlib (and POSIX) so I don't have to think about these #include #include #include #include #include #include #include #include #include // Wayland includes #include "wayland-client.h" #include "session-lock.h" #define LOCK_MANAGER_NAME "ext_session_lock_manager_v1" // global state struct wl_display * wl = NULL; struct wl_registry * reg = NULL; struct ext_session_lock_manager_v1 * lockmgr = NULL; struct ext_session_lock_v1 * lock = NULL; enum lock_state {LOCKED, FINISHED, UNSET} lock_state = UNSET; static void registry_global_handler(void * data, struct wl_registry * wl_registry, uint32_t name, const char * interface, uint32_t version) { printf("UwU, iface %s (name %d) appeared!\n", interface, name); if (strcmp(interface, LOCK_MANAGER_NAME) == 0) { // fire the bind outright lockmgr = wl_registry_bind(wl_registry, name, &ext_session_lock_manager_v1_interface, 1/*version, we don't know anything newer*/); } } static void registry_global_remove_handler(void * data, struct wl_registry * wl_registry, uint32_t name) { printf("OwO, iface %d disappeared, should destroy!\n", name); } static void callback_done_handler(void * data, struct wl_callback * wl_callback, uint32_t callback_data) { printf("Heh, callback done!\n"); } static void lock_locked_handler(void * data, struct ext_session_lock_v1 * lock) { enum lock_state * state = (enum lock_state *)data; *state = LOCKED; } static void lock_finished_handler(void * data, struct ext_session_lock_v1 * lock) { enum lock_state * state = (enum lock_state *)data; *state = FINISHED; } int main(void) { // get wl_display, the core object wl = wl_display_connect(NULL); if (wl == NULL) { fprintf(stderr, "Cannot connect to compositor, no wayland?\n"); return 1; } // prepare listeners for wl_registry.global struct wl_registry_listener reg_listener = { .global = ®istry_global_handler, .global_remove = ®istry_global_remove_handler, }; reg = wl_display_get_registry(wl); wl_registry_add_listener(reg, ®_listener, NULL); // add the barrier to the end struct wl_callback * cbk = wl_display_sync(wl); struct wl_callback_listener cbk_l = { .done = &callback_done_handler, }; wl_callback_add_listener(cbk, &cbk_l, NULL); // process the queue wl_display_dispatch(wl); if (lockmgr == NULL) { fprintf(stderr, "No support for un/locking, no fun.\n"); return 1; } lock = ext_session_lock_manager_v1_lock(lockmgr); struct ext_session_lock_v1_listener lock_l = { .locked = &lock_locked_handler, .finished = &lock_finished_handler, }; ext_session_lock_v1_add_listener(lock, &lock_l, &lock_state); // process the queue wl_display_dispatch(wl); if (lock_state == UNSET) { fprintf(stderr, "BUG!\n"); return 1; } else if (lock_state == FINISHED) { printf("Cannot get lock – either another lock is running or not lockable.\n"); // nothing to do, just destroy stuff ext_session_lock_v1_destroy(lock); } else if (lock_state == LOCKED) { printf("Unlocking…\n"); ext_session_lock_v1_unlock_and_destroy(lock); } else { fprintf(stderr, "DAFUQ?\n"); return 1; } // just for completeness: destroy the objects we created. Also, set NULL for safety. printf("Cleaning up…\n"); // lock is destroyed already lock = NULL; ext_session_lock_manager_v1_destroy(lockmgr); lockmgr = NULL; wl_registry_destroy(reg); reg = NULL; // Display is special, that is diconnected and not destroyed. // Also, make the roundtrip beforehand // FIXME: is wl_display_roundtrip the thing we want? What does it return? wl_display_roundtrip(wl); wl_display_disconnect(wl); wl = NULL; printf("Done lol\n"); return 0; }