JezerM
3 years ago
7 changed files with 143 additions and 63 deletions
@ -0,0 +1,64 @@
|
||||
#include <stdlib.h> |
||||
#include <stdbool.h> |
||||
#include <X11/Xos.h> |
||||
#include <X11/Xlib.h> |
||||
|
||||
Display* OpenDisplay() { |
||||
char *disp = NULL; |
||||
Display *display = XOpenDisplay(disp); |
||||
return display; |
||||
} |
||||
|
||||
typedef struct { |
||||
int timeout; |
||||
int interval; |
||||
int prefer_blank; |
||||
int allow_exp; |
||||
} ScreenSaver; |
||||
|
||||
ScreenSaver *get_screensaver() { |
||||
int timeout, interval, prefer_blank, allow_exp; |
||||
|
||||
Display *display = OpenDisplay(); |
||||
if (display == NULL) return NULL; |
||||
|
||||
XGetScreenSaver(display, &timeout, &interval, &prefer_blank, &allow_exp); |
||||
XCloseDisplay(display); |
||||
|
||||
ScreenSaver *data = malloc(sizeof *data); |
||||
data->timeout = timeout; |
||||
data->interval = interval; |
||||
data->prefer_blank = prefer_blank; |
||||
data->allow_exp = allow_exp; |
||||
|
||||
return data; |
||||
} |
||||
|
||||
void set_screensaver(int timeout, int interval, int prefer_blank, int allow_exp) { |
||||
int timeout_i, interval_i, prefer_blank_i, allow_exp_i; |
||||
|
||||
Display *display = OpenDisplay(); |
||||
if (display == NULL) return; |
||||
XGetScreenSaver(display, &timeout_i, &interval_i, &prefer_blank_i, &allow_exp_i); |
||||
|
||||
if (timeout != -1) timeout_i = timeout; |
||||
if (interval != -1) interval_i = interval; |
||||
if (prefer_blank != -1) prefer_blank_i = prefer_blank; |
||||
if (allow_exp != -1) allow_exp_i = allow_exp; |
||||
|
||||
XSetScreenSaver(display, timeout_i, interval_i, prefer_blank_i, allow_exp_i); |
||||
|
||||
XCloseDisplay(display); |
||||
} |
||||
|
||||
void force_screensaver(bool value) { |
||||
Display *display = OpenDisplay(); |
||||
if (display == NULL) return; |
||||
|
||||
if (value == true) |
||||
XForceScreenSaver(display, ScreenSaverActive); |
||||
else |
||||
XForceScreenSaver(display, ScreenSaverReset); |
||||
|
||||
XCloseDisplay(display); |
||||
} |
@ -0,0 +1,76 @@
|
||||
import ctypes |
||||
import os |
||||
from typing import Union |
||||
from logger import logger |
||||
|
||||
|
||||
class ScreenSaverData(ctypes.Structure): |
||||
"""Screensaver data""" |
||||
_fields_ = [ |
||||
("timeout", ctypes.c_int), |
||||
("interval", ctypes.c_int), |
||||
("prefer_blank", ctypes.c_int), |
||||
("allow_exp", ctypes.c_int), |
||||
] |
||||
|
||||
def __str__(self): |
||||
timeout = getattr(self, "timeout") |
||||
interval = getattr(self, "interval") |
||||
prefer_blank = getattr(self, "prefer_blank") |
||||
allow_exp = getattr(self, "allow_exp") |
||||
return f"{timeout} {interval} {prefer_blank} {allow_exp}" |
||||
|
||||
ScreenSaverDataPointer = ctypes.POINTER(ScreenSaverData) |
||||
|
||||
class ScreenSaver: |
||||
"""Screensaver wrapper""" |
||||
|
||||
saved_data: Union[ScreenSaverData, None] |
||||
saved: bool = False |
||||
|
||||
def __init__(self): |
||||
dir = os.path.dirname(os.path.realpath(__file__)) |
||||
libname = os.path.join(dir, "_screensaver.so") |
||||
self.clib = ctypes.CDLL(libname) |
||||
self.clib.get_screensaver.restype = ScreenSaverDataPointer |
||||
|
||||
def get_screensaver(self): |
||||
"""Gets screensaver data""" |
||||
data: ScreenSaverDataPointer = self.clib.get_screensaver() |
||||
if data is None: |
||||
return |
||||
contents: ScreenSaverData = data.contents |
||||
return contents |
||||
|
||||
def set_screensaver(self, timeout = -1, interval = -1, prefer_blank = -1, allow_exp = -1): |
||||
"""Sets screensaver properties""" |
||||
if self.saved: |
||||
return |
||||
self.saved_data = self.get_screensaver() |
||||
self.saved = True |
||||
self.clib.set_screensaver( |
||||
ctypes.c_int(timeout), |
||||
ctypes.c_int(interval), |
||||
ctypes.c_int(prefer_blank), |
||||
ctypes.c_int(allow_exp) |
||||
) |
||||
logger.debug("Screensaver timeout set") |
||||
|
||||
def reset_screensaver(self): |
||||
"""Reset screensaver""" |
||||
if not self.saved or not self.saved_data: |
||||
return |
||||
self.clib.set_screensaver( |
||||
ctypes.c_int(getattr(self.saved_data, "timeout")), |
||||
ctypes.c_int(getattr(self.saved_data, "interval")), |
||||
ctypes.c_int(getattr(self.saved_data, "prefer_blank")), |
||||
ctypes.c_int(getattr(self.saved_data, "allow_exp")) |
||||
) |
||||
self.saved = False |
||||
logger.debug("Screensaver reset") |
||||
|
||||
def force_screensaver(self, value: bool): |
||||
"""Force screensaver""" |
||||
self.clib.force_screensaver(ctypes.c_bool(value)) |
||||
|
||||
screensaver = ScreenSaver() |
@ -1,60 +0,0 @@
|
||||
from Xlib import X |
||||
from Xlib.display import Display |
||||
from Xlib.error import DisplayError |
||||
from logger import logger |
||||
|
||||
class Screensaver: |
||||
"""Screensaver class""" |
||||
|
||||
display: Display |
||||
available: bool = False |
||||
saved_data: dict[str, int] |
||||
saved: bool = False |
||||
|
||||
def __init__(self): |
||||
self.init_display() |
||||
|
||||
def init_display(self): |
||||
"""Init display""" |
||||
try: |
||||
self.display = Display() |
||||
self.available = True |
||||
except DisplayError as err: |
||||
logger.error("Xlib error: %s", err) |
||||
|
||||
def set_screensaver(self, timeout: int): |
||||
"""Set screensaver timeout""" |
||||
if self.saved or not self.available: |
||||
return |
||||
self.display.sync() |
||||
self.display.sync() |
||||
# pylint: disable-next=protected-access |
||||
data: dict[str, int] = self.display.get_screen_saver()._data or {} |
||||
self.saved_data = data |
||||
self.saved = True |
||||
|
||||
self.display.set_screen_saver(timeout, |
||||
data["interval"], |
||||
data["prefer_blanking"], |
||||
data["allow_exposures"]) |
||||
self.display.flush() |
||||
logger.debug("Screensaver timeout set") |
||||
|
||||
def reset_screensaver(self): |
||||
"""Reset screensaver""" |
||||
if not self.saved or not self.available: |
||||
return |
||||
self.display.sync() |
||||
self.display.set_screen_saver(self.saved_data["timeout"], |
||||
self.saved_data["interval"], |
||||
self.saved_data["prefer_blanking"], |
||||
self.saved_data["allow_exposures"]) |
||||
self.display.flush() |
||||
self.saved = False |
||||
logger.debug("Screensaver reset") |
||||
|
||||
def force_screensaver(self, value: bool): |
||||
"""Force screensaver""" |
||||
self.display.force_screen_saver(X.ScreenSaverActive if value else X.ScreenSaverReset) |
||||
|
||||
screensaver = Screensaver() |
Loading…
Reference in new issue