Skip to content

Commit

Permalink
Merge pull request #74 from crogers1/brightness
Browse files Browse the repository at this point in the history
Power Management Subsystem Enhancements and Bugfixes
  • Loading branch information
jandryuk authored Oct 25, 2022
2 parents 7332959 + f2e3d7d commit 22a9f06
Show file tree
Hide file tree
Showing 17 changed files with 864 additions and 33 deletions.
2 changes: 2 additions & 0 deletions xcpmd/configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ LT_INIT
# Check for libraries
AC_SEARCH_LIBS([dlopen], [dl])
AC_SEARCH_LIBS([yajl_tree_parse], [yajl])
AC_SEARCH_LIBS([round], [m])
AC_SEARCH_LIBS([udev_new], [udev])

# Required modules.
PKG_CHECK_MODULES([LIBPCI], [libpci])
Expand Down
26 changes: 24 additions & 2 deletions xcpmd/src/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,14 @@ noinst_HEADERS = \
battery.h \
parser.h \
db-helper.h \
vm-utils.h
vm-utils.h \
backlight.h

sbin_PROGRAMS = xcpmd

xcpmd_SOURCES = \
acpi-events.c \
backlight.c \
battery.c \
db-helper.c \
modules.c \
Expand Down Expand Up @@ -57,7 +59,7 @@ xcpmd_LDFLAGS = -rdynamic
#
# RPC generated stubs.
#
DBUS_CLIENT_IDLS = xenmgr xenmgr_vm db vglass input_daemon
DBUS_CLIENT_IDLS = xenmgr xenmgr_vm xenmgr_host db vglass input_daemon
DBUS_SERVER_IDLS = xcpmd

BUILT_SOURCES = \
Expand All @@ -79,9 +81,11 @@ rpcgen/%_server_marshall.h rpcgen/%_server_obj.h rpcgen/%_server_obj.c: $(IDLDIR
#
pkglib_LTLIBRARIES = \
acpi-module.la \
db-events-module.la \
default-actions-module.la \
default-inputs-module.la \
displayhandler-module.la \
host-power-module.la \
idle-detect-module.la \
vm-actions-module.la \
vm-events-module.la
Expand Down Expand Up @@ -140,3 +144,21 @@ vm_events_module_la_SOURCES = \
vm-utils.h \
xcpmd.h
vm_events_module_la_LDFLAGS = -avoid-version -module -shared

host_power_module_la_SOURCES = \
host-power-module.c \
project.h \
xcpmd.h \
rules.h \
vm-utils.h
host_power_module_la_LDFLAGS = -avoid-version -module -shared

db_events_module_la_SOURCES = \
db-events-module.c \
project.h \
xcpmd.h \
modules.h \
rules.h \
db-events-module.h \
db-helper.h
db_events_module_la_LDFLAGS = -avoid-version -module -shared
23 changes: 5 additions & 18 deletions xcpmd/src/acpi-events.c
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ static void handle_battery_status_event(int battery_index) {
*/


static void handle_lid_event(int status) {
void handle_lid_event(int status) {

int lid_status;
char * lid_status_string;
Expand Down Expand Up @@ -460,20 +460,7 @@ static void process_acpi_message(char *acpi_buffer, ssize_t len) {
return;
}

if (!strcmp(subclass, ACPI_BUTTON_SUBCLASS_LID)) {

if (tokens[2] == NULL)
data = LID_UNKNOWN;
else if (!strcmp(tokens[2], "open"))
data = LID_OPEN;
else if (!strcmp(tokens[2], "close"))
data = LID_CLOSED;
else
data = LID_UNKNOWN;

handle_lid_event(data);
}
else if (!strcmp(subclass, ACPI_BUTTON_SUBCLASS_POWER)) {
if (!strcmp(subclass, ACPI_BUTTON_SUBCLASS_POWER)) {
handle_power_button_event();
}
else if (!strcmp(subclass, ACPI_BUTTON_SUBCLASS_SLEEP)) {
Expand Down Expand Up @@ -630,8 +617,9 @@ int acpi_events_initialize(void) {
//notifications before data is ready on a hardware level. If a quirk is added
//to the battery driver for these platforms, we can move to an event-driven
//model.
event_set(&refresh_battery_event, -1, EV_TIMEOUT | EV_PERSIST, wrapper_refresh_battery_event, NULL);
wrapper_refresh_battery_event(0, 0, NULL);
event_set(&refresh_battery_event, -1, EV_TIMEOUT | EV_PERSIST, wrapper_refresh_battery_event,
acpi_event_table);
wrapper_refresh_battery_event(0, 0, acpi_event_table);

//State must be initialized after acpi-module is loaded--call it from main().

Expand Down Expand Up @@ -666,4 +654,3 @@ void handle_battery_events(void) {
handle_events(status_e);
}
}

2 changes: 2 additions & 0 deletions xcpmd/src/acpi-events.h
Original file line number Diff line number Diff line change
Expand Up @@ -130,4 +130,6 @@
#define ACPI_VIDEO_SUBCLASS_BRTCYCLE "brightnesscycle"
#define ACPI_VIDEO_SUBCLASS_TABLETMODE "tabletmode"

void handle_lid_event(int status);

#endif
87 changes: 87 additions & 0 deletions xcpmd/src/acpi-module.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@
#include "rules.h"
#include "acpi-module.h"
#include "battery.h"
#include "backlight.h"
#include "vm-utils.h"
#include "acpi-events.h"

/**
* This module listens for ACPI events from acpid.
Expand All @@ -53,6 +56,10 @@ bool battery_present (struct ev_wrapper * event, struct arg_node *
bool overall_battery_greater_than (struct ev_wrapper * event, struct arg_node * args);
bool overall_battery_less_than (struct ev_wrapper * event, struct arg_node * args);
bool overall_battery_equal_to (struct ev_wrapper * event, struct arg_node * args);
void set_backlight (struct arg_node * args);
void increase_backlight (struct arg_node * args);
void decrease_backlight (struct arg_node * args);
static DBusHandlerResult lid_event_handler(DBusConnection * connection, DBusMessage * dbus_message, void * user_data);


//Private data structures
Expand All @@ -73,6 +80,13 @@ struct cond_table_row {
void (* on_instantiate)(struct condition *);
};

struct action_table_row {
char * name;
void (* func)(struct arg_node *);
char * prototype;
char * pretty_prototype;
};


//Private data
static struct event_data_row event_data[] = {
Expand Down Expand Up @@ -110,8 +124,15 @@ static struct cond_table_row condition_data[] = {
{"whileOverallBattEqualTo" , overall_battery_equal_to , "i" , "int percentage" , EVENT_BATT_STATUS , NULL }
};

static struct action_table_row action_table[] = {
{"setBacklight" , set_backlight , "i" , "int backlight_percent" } ,
{"increaseBacklight" , increase_backlight , "i" , "int percent_to_increase"} ,
{"decreaseBacklight" , decrease_backlight , "i" , "int percent_to_decrease"}
};

static unsigned int num_conditions = sizeof(condition_data) / sizeof(condition_data[0]);
static unsigned int num_events = sizeof(event_data) / sizeof(event_data[0]);
static unsigned int num_action_types = sizeof(action_table) / sizeof(action_table[0]);


//Public data
Expand Down Expand Up @@ -143,15 +164,27 @@ __attribute__((constructor)) static void init_module() {
struct cond_table_row entry = condition_data[i];
add_condition_type(entry.name, entry.func, entry.prototype, entry.pretty_prototype, _acpi_event_table[entry.event_index], entry.on_instantiate);
}

//Add all action_types to the action list
for (i=0; i < num_action_types; ++i) {
add_action_type(action_table[i].name, action_table[i].func, action_table[i].prototype, action_table[i].pretty_prototype);
}

//initialize backlight module
backlight_init();
add_dbus_filter("type='signal',interface='com.citrix.xenclient.input',member='lid_state_changed'", lid_event_handler, NULL, NULL);
}


//Cleans up after this module.
//The destructor attribute causes this to run at unload (dlclose()) time.
__attribute__((destructor)) static void uninit_module() {

//cleanup backlight module
backlight_destroy();
//Free event table.
free(_acpi_event_table);
remove_dbus_filter("type='signal',interface='com.citrix.xenclient.input',member='lid_state_changed'", lid_event_handler, NULL);
}


Expand Down Expand Up @@ -211,6 +244,42 @@ bool lid_closed(struct ev_wrapper * event, struct arg_node * args) {
}


/*
* lid_event_handler handles lid_state_changed signals when they are received
* over dbus. The lid_state_changed signal is emitted from vglass after libinput
* detects SW_LID and EV_SW. The signal includes one boolean argument
* indicating whether the lid was opened or closed. The argument is retrieved
* from the dbus signal, and passed along to the handle_lid_event function,
* which will then update xenstore accordingly.
*
* The passed argument will include either a boolean true (1) to indicate
* a closed lid or false (0) to indicate an open lid. These values come from
* LIBINPUT_SWITCH_STATE_ON/OFF and match the enum values of LID_STATE located
* in xcpmd.h. This matters because handle_lid_event checks the value passed to
* it against that enum, and then sets xenstore based on that value.
*/
DBusHandlerResult lid_event_handler(DBusConnection * connection, DBusMessage * dbus_message, void * user_data) {

DBusError error;
bool lid_status;
DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;

if (dbus_message_is_signal(dbus_message, "com.citrix.xenclient.input", "lid_state_changed")) {

dbus_error_init(&error);
if (!dbus_message_get_args(dbus_message, &error, DBUS_TYPE_BOOLEAN, &lid_status, DBUS_TYPE_INVALID)) {
xcpmd_log(LOG_ERR, "dbus_message_get_args() failed: %s (%s).\n", error.name, error.message);
}
dbus_error_free(&error);

handle_lid_event(lid_status);
ret = DBUS_HANDLER_RESULT_HANDLED;
}

return ret;
}


bool tablet_mode(struct ev_wrapper * event, struct arg_node * args) {

return event->value.i == TABLET_MODE;
Expand Down Expand Up @@ -270,3 +339,21 @@ bool overall_battery_equal_to(struct ev_wrapper * event, struct arg_node * args)
int percentage = get_arg(args, 0)->arg.i;
return get_overall_battery_percentage() == percentage;
}

void set_backlight(struct arg_node * args) {

struct arg_node * node = get_arg(args, 0);
backlight_set(node->arg.i);
}

void increase_backlight(struct arg_node * args) {

struct arg_node * node = get_arg(args, 0);
backlight_increase(node->arg.i);
}

void decrease_backlight(struct arg_node * args) {

struct arg_node * node = get_arg(args, 0);
backlight_decrease(node->arg.i);
}
Loading

0 comments on commit 22a9f06

Please sign in to comment.