41 lines
2.2 KiB
C
41 lines
2.2 KiB
C
/* Disposable protocol locker: no credentials, no PAM bypass in real locker.
|
|
* Blank lock frames are presented by the compositor on every physical output.
|
|
* The release file instructs this actual protocol owner to unlock normally. */
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <poll.h>
|
|
#include <unistd.h>
|
|
#include <wayland-client.h>
|
|
#include "ext-session-lock-client-protocol.h"
|
|
static struct ext_session_lock_manager_v1 *manager;
|
|
static int confirmed, outputs;
|
|
static void global(void *d, struct wl_registry *r, uint32_t n, const char *i, uint32_t v) {
|
|
(void)d; (void)v;
|
|
if (!strcmp(i,"ext_session_lock_manager_v1")) manager=wl_registry_bind(r,n,&ext_session_lock_manager_v1_interface,1);
|
|
if (!strcmp(i,"wl_output")) outputs++;
|
|
}
|
|
static void removed(void *d, struct wl_registry *r, uint32_t n) {(void)d;(void)r;(void)n;}
|
|
static void locked(void *d, struct ext_session_lock_v1 *l) {
|
|
(void)d;(void)l;confirmed=1;printf("{\"event\":\"locked\",\"outputs\":%d}\n",outputs);fflush(stdout);
|
|
}
|
|
static void finished(void *d, struct ext_session_lock_v1 *l) {(void)d;(void)l;exit(3);}
|
|
int main(int argc,char **argv) {
|
|
if (argc!=2 || !getenv("FERESE_TEST_LOCK") || strcmp(getenv("FERESE_TEST_LOCK"),"1")) return 2;
|
|
struct wl_display *display=wl_display_connect(NULL);if(!display)return 1;
|
|
struct wl_registry *registry=wl_display_get_registry(display);
|
|
const struct wl_registry_listener r={global,removed};wl_registry_add_listener(registry,&r,NULL);
|
|
if(wl_display_roundtrip(display)<0 || !manager)return 1;
|
|
struct ext_session_lock_v1 *lock=ext_session_lock_manager_v1_lock(manager);
|
|
const struct ext_session_lock_v1_listener listener={locked,finished};ext_session_lock_v1_add_listener(lock,&listener,NULL);
|
|
for (;;) {
|
|
if(wl_display_dispatch_pending(display)<0 || wl_display_flush(display)<0)return 1;
|
|
if(confirmed && access(argv[1],F_OK)==0) {
|
|
ext_session_lock_v1_unlock_and_destroy(lock);wl_display_roundtrip(display);
|
|
puts("{\"event\":\"unlocked\"}");return 0;
|
|
}
|
|
struct pollfd fd={wl_display_get_fd(display),POLLIN,0};
|
|
if(poll(&fd,1,100)>0 && wl_display_dispatch(display)<0)return 1;
|
|
}
|
|
}
|