sin: proper login1 inhibit handler

Signed-off-by: NotAShelf <raf@notashelf.dev>
Change-Id: Ie2b8ff515fb02c10f2e9034d78a53be06a6a6964
This commit is contained in:
raf 2026-04-13 11:23:13 +03:00
commit c89f4b5d02
Signed by: NotAShelf
GPG key ID: 29D95B64378DB4BF

236
src/inhibit-manager.c Normal file
View file

@ -0,0 +1,236 @@
#include "inhibit-interface.h"
#include <stdio.h>
#include <string.h>
int inhibit_manager_init(InhibitManager* mgr) {
if (!mgr)
return -1;
memset(mgr, 0, sizeof(*mgr));
return 0;
}
void inhibit_manager_cleanup(InhibitManager* mgr) {
if (!mgr)
return;
for (int i = 0; i < mgr->num_inhibits; i++) {
TrackedInhibit* tracked = &mgr->inhibits[i];
InhibitInterface* iface = mgr->interfaces[tracked->interface_idx];
if (iface && iface->uninhibit) {
iface->uninhibit(iface, &tracked->entry);
}
}
for (int i = 0; i < mgr->num_interfaces; i++) {
if (mgr->interfaces[i] && mgr->interfaces[i]->cleanup) {
mgr->interfaces[i]->cleanup(mgr->interfaces[i]);
}
}
memset(mgr, 0, sizeof(*mgr));
}
int inhibit_manager_register(InhibitManager* mgr, InhibitInterface* iface) {
if (!mgr || !iface || mgr->num_interfaces >= MAX_INTERFACES) {
return -1;
}
iface->enabled = 1;
mgr->interfaces[mgr->num_interfaces] = iface;
iface->set_callback(iface, mgr->event_callback);
if (iface->init(iface) < 0) {
fprintf(stderr, "Failed to initialize interface: %s\n", iface->name);
iface->enabled = 0;
return -1;
}
mgr->num_interfaces++;
return 0;
}
void inhibit_manager_set_callback(InhibitManager* mgr, InhibitEventCallback cb) {
if (!mgr)
return;
mgr->event_callback = cb;
for (int i = 0; i < mgr->num_interfaces; i++) {
if (mgr->interfaces[i] && mgr->interfaces[i]->set_callback) {
mgr->interfaces[i]->set_callback(mgr->interfaces[i], cb);
}
}
}
TrackedInhibit* inhibit_manager_find(InhibitManager* mgr, InhibitInterface* source,
const char* id) {
if (!mgr || !id)
return NULL;
for (int i = 0; i < mgr->num_inhibits; i++) {
TrackedInhibit* tracked = &mgr->inhibits[i];
if (strcmp(tracked->entry.id, id) == 0) {
if (!source || mgr->interfaces[tracked->interface_idx] == source) {
return tracked;
}
}
}
return NULL;
}
int inhibit_manager_add_tracked(InhibitManager* mgr, InhibitInterface* source,
const InhibitEntry* entry) {
if (!mgr || !source || !entry ||
mgr->num_inhibits >= (MAX_INTERFACES * MAX_INHIBITS_PER_INTERFACE)) {
return -1;
}
int source_idx = -1;
for (int i = 0; i < mgr->num_interfaces; i++) {
if (mgr->interfaces[i] == source) {
source_idx = i;
break;
}
}
if (source_idx < 0)
return -1;
TrackedInhibit* tracked = &mgr->inhibits[mgr->num_inhibits];
memcpy(&tracked->entry, entry, sizeof(*entry));
tracked->interface_idx = source_idx;
tracked->num_forwarded = 0;
mgr->num_inhibits++;
return 0;
}
void inhibit_manager_remove_tracked(InhibitManager* mgr, InhibitInterface* source, const char* id) {
if (!mgr || !id)
return;
for (int i = 0; i < mgr->num_inhibits; i++) {
TrackedInhibit* tracked = &mgr->inhibits[i];
if (strcmp(tracked->entry.id, id) == 0) {
if (!source || mgr->interfaces[tracked->interface_idx] == source) {
for (int j = i; j < mgr->num_inhibits - 1; j++) {
mgr->inhibits[j] = mgr->inhibits[j + 1];
}
mgr->num_inhibits--;
return;
}
}
}
}
int inhibit_manager_forward_inhibit(InhibitManager* mgr, InhibitInterface* source,
const InhibitEntry* entry) {
if (!mgr || !source || !entry)
return -1;
if (entry->flags & INHIBIT_FLAG_FORWARDED) {
return 0;
}
TrackedInhibit* tracked = inhibit_manager_find(mgr, source, entry->id);
if (!tracked) {
inhibit_manager_add_tracked(mgr, source, entry);
tracked = inhibit_manager_find(mgr, source, entry->id);
}
if (!tracked)
return -1;
for (int i = 0; i < mgr->num_interfaces; i++) {
InhibitInterface* target = mgr->interfaces[i];
if (target == source || !target->enabled || !target->inhibit) {
continue;
}
int already_forwarded = 0;
for (int j = 0; j < tracked->num_forwarded; j++) {
if (strcmp(tracked->forwarded_to[j], target->name) == 0) {
already_forwarded = 1;
break;
}
}
if (already_forwarded)
continue;
InhibitEntry forwarded_entry = *entry;
forwarded_entry.flags |= INHIBIT_FLAG_FORWARDED;
memset(forwarded_entry.id, 0, sizeof(forwarded_entry.id));
if (target->inhibit(target, entry->type, entry->app_name, entry->reason, &forwarded_entry) ==
0) {
if (tracked->num_forwarded < MAX_INTERFACES) {
strncpy(tracked->forwarded_to[tracked->num_forwarded], target->name, INHIBIT_ID_LEN - 1);
tracked->num_forwarded++;
} else {
fprintf(stderr, "Warning: inhibit forwarded to %s but tracking limit reached\n",
target->name);
}
}
}
return 0;
}
int inhibit_manager_forward_uninhibit(InhibitManager* mgr, InhibitInterface* source,
const InhibitEntry* entry) {
if (!mgr || !source || !entry)
return -1;
TrackedInhibit* tracked = inhibit_manager_find(mgr, source, entry->id);
if (!tracked)
return -1;
for (int i = 0; i < tracked->num_forwarded; i++) {
for (int j = 0; j < mgr->num_interfaces; j++) {
InhibitInterface* target = mgr->interfaces[j];
if (strcmp(target->name, tracked->forwarded_to[i]) == 0 && target->uninhibit) {
target->uninhibit(target, &tracked->entry);
break;
}
}
}
inhibit_manager_remove_tracked(mgr, source, entry->id);
return 0;
}
void inhibit_manager_poll_all(InhibitManager* mgr) {
if (!mgr)
return;
for (int i = 0; i < mgr->num_interfaces; i++) {
InhibitInterface* iface = mgr->interfaces[i];
if (iface->enabled && iface->poll) {
iface->poll(iface);
}
}
}
const char* inhibit_type_to_string(InhibitType type) {
switch (type) {
case INHIBIT_TYPE_SCREENSAVER:
return "screensaver";
case INHIBIT_TYPE_SUSPEND:
return "suspend";
case INHIBIT_TYPE_IDLE:
return "idle";
default:
return "unknown";
}
}
InhibitType inhibit_type_from_string(const char* str) {
if (!str)
return INHIBIT_TYPE_IDLE;
if (strcmp(str, "screensaver") == 0)
return INHIBIT_TYPE_SCREENSAVER;
if (strcmp(str, "suspend") == 0)
return INHIBIT_TYPE_SUSPEND;
if (strcmp(str, "idle") == 0)
return INHIBIT_TYPE_IDLE;
return INHIBIT_TYPE_IDLE;
}