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