diff --git a/src/bin/e_int_menus.c b/src/bin/e_int_menus.c index 5db55db19..560257ce7 100644 --- a/src/bin/e_int_menus.c +++ b/src/bin/e_int_menus.c @@ -12,6 +12,7 @@ struct _Main_Data E_Menu *enlightenment; E_Menu *config; E_Menu *lost_clients; + E_Menu *inhibitors; }; /* local subsystem functions */ @@ -63,6 +64,7 @@ static void _e_int_menus_desk_item_cb(void *data, E_Menu *m, E_Menu_Item static void _e_int_menus_item_label_set(Efreet_Menu *entry, E_Menu_Item *mi); static Efreet_Menu *_e_int_menus_apps_thread_new(E_Menu *m, const char *dir); static Eina_Bool _e_int_menus_efreet_desktop_cache_update(void *d, int type, void *e); +static void _e_int_menus_inhibit_cb(void *data, E_Menu *m, E_Menu_Item *mi); //static void _e_int_menus_apps_drag_finished(E_Drag *drag, int dropped EINA_UNUSED); /* local subsystem globals */ @@ -194,6 +196,16 @@ e_int_menus_main_new(void) e_util_menu_item_theme_icon_set(mi, "preferences-desktop"); e_menu_item_submenu_set(mi, subm); + if ((e_msgbus_data) && (e_msgbus_data->screensaver_inhibits)) + { + subm = e_int_menus_inhibitors_new(); + dat->inhibitors = subm; + mi = e_menu_item_new(m); + e_menu_item_label_set(mi, _("Blanking Block")); + e_util_menu_item_theme_icon_set(mi, "preferences-screen-normal"); + e_menu_item_submenu_set(mi, subm); + } + subm = e_int_menus_clients_new(); dat->clients = subm; mi = e_menu_item_new(m); @@ -418,6 +430,37 @@ e_int_menus_lost_clients_new(void) return m; } +static void +_e_int_menus_inhibit_cb(void *data, E_Menu *m EINA_UNUSED, E_Menu_Item *mi EINA_UNUSED) +{ + uintptr_t cookie = (uintptr_t)data; + + e_msgbus_screensaver_inhibit_remove((unsigned int)cookie); +} + +E_API E_Menu * +e_int_menus_inhibitors_new(void) +{ + E_Menu *m; + E_Menu_Item *mi; + Eina_List *l; + E_Msgbus_Data_Screensaver_Inhibit *inhibit; + + m = e_menu_new(); + if (!((e_msgbus_data) && (e_msgbus_data->screensaver_inhibits))) + return NULL; + EINA_LIST_FOREACH(e_msgbus_data->screensaver_inhibits, l, inhibit) + { + mi = e_menu_item_new(m); + e_menu_item_label_set(mi, inhibit->application); + e_menu_item_check_set(mi, 1); + e_menu_item_toggle_set(mi, 1); + e_menu_item_callback_set(mi, _e_int_menus_inhibit_cb, + (void *)((uintptr_t)inhibit->cookie)); + } + return m; +} + E_API E_Int_Menu_Augmentation * e_int_menus_menu_augmentation_add_sorted(const char *menu, const char *sort_key, @@ -593,6 +636,7 @@ _e_int_menus_main_del_hook(void *obj) if (dat->lost_clients) e_object_del(E_OBJECT(dat->lost_clients)); if (dat->enlightenment) e_object_del(E_OBJECT(dat->enlightenment)); if (dat->config) e_object_del(E_OBJECT(dat->config)); + if (dat->inhibitors) e_object_del(E_OBJECT(dat->inhibitors)); free(dat); _e_int_menus_augmentation_del(m, _e_int_menus_augmentation_find("main/0")); diff --git a/src/bin/e_int_menus.h b/src/bin/e_int_menus.h index bc7d29042..9e7b162d9 100644 --- a/src/bin/e_int_menus.h +++ b/src/bin/e_int_menus.h @@ -67,6 +67,7 @@ E_API E_Menu *e_int_menus_all_apps_new(void); E_API E_Menu *e_int_menus_config_new(void); E_API E_Menu *e_int_menus_lost_clients_new(void); E_API E_Menu *e_int_menus_shelves_new(void); +E_API E_Menu *e_int_menus_inhibitors_new(void); E_API E_Int_Menu_Augmentation *e_int_menus_menu_augmentation_add(const char *menu, void (*func_add) (void *data, E_Menu *m), diff --git a/src/bin/e_msgbus.c b/src/bin/e_msgbus.c index bb1102003..c228e354d 100644 --- a/src/bin/e_msgbus.c +++ b/src/bin/e_msgbus.c @@ -1,17 +1,15 @@ #include "e.h" +/////////////////////////////////////////////////////////////////////////// #define E_BUS "org.enlightenment.wm.service" #define E_IFACE "org.enlightenment.wm.service" #define E_PATH "/org/enlightenment/wm/RemoteObject" - -/* local subsystem functions */ -static void _e_msgbus_request_name_cb(void *data, const Eldbus_Message *msg, Eldbus_Pending *pending); - +static void _e_msgbus_core_request_name_cb(void *data, const Eldbus_Message *msg, Eldbus_Pending *pending); static Eldbus_Message *_e_msgbus_core_version_cb(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg); static Eldbus_Message *_e_msgbus_core_restart_cb(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg); static Eldbus_Message *_e_msgbus_core_shutdown_cb(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg); -static const Eldbus_Method core_methods[] = +static const Eldbus_Method _e_core_methods[] = { { "Version", NULL, ELDBUS_ARGS({"s", "version"}), _e_msgbus_core_version_cb, 0 }, { "Restart", NULL, NULL, _e_msgbus_core_restart_cb, 0 }, @@ -19,60 +17,96 @@ static const Eldbus_Method core_methods[] = { NULL, NULL, NULL, NULL, 0} }; -static const Eldbus_Service_Interface_Desc core_desc = { - E_IFACE, core_methods, NULL, NULL, NULL, NULL +static const Eldbus_Service_Interface_Desc _e_core_desc = { + E_IFACE, _e_core_methods, NULL, NULL, NULL, NULL +}; +/////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////// +#define SCREENSAVER_BUS "org.freedesktop.ScreenSaver" +#define SCREENSAVER_IFACE "org.freedesktop.ScreenSaver" +#define SCREENSAVER_PATH "/org/freedesktop/ScreenSaver" +static void _e_msgbus_screensaver_request_name_cb(void *data, const Eldbus_Message *msg, Eldbus_Pending *pending); +static void _e_msgbus_screensaver_inhibit_free(E_Msgbus_Data_Screensaver_Inhibit *inhibit); +static void _e_msgbus_screensaver_owner_change_cb(void *data EINA_UNUSED, const char *bus, const char *old_id, const char *new_id); +static Eldbus_Message *_e_msgbus_screensaver_inhibit_cb(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg); +static Eldbus_Message *_e_msgbus_screensaver_uninhibit_cb(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg); +static Eldbus_Message *_e_msgbus_screensaver_getactive_cb(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg); + +static const Eldbus_Method _screensaver_core_methods[] = +{ + { "Inhibit", ELDBUS_ARGS({"s", "application_name"}, {"s", "reason_for_inhibit"}), ELDBUS_ARGS({"u", "cookie"}), _e_msgbus_screensaver_inhibit_cb, 0 }, + { "UnInhibit", ELDBUS_ARGS({"u", "cookie"}), NULL, _e_msgbus_screensaver_uninhibit_cb, 0 }, + { "GetActive", NULL, ELDBUS_ARGS({"b", "active"}), _e_msgbus_screensaver_getactive_cb, 0 }, + { NULL, NULL, NULL, NULL, 0} }; -/* local subsystem globals */ -static E_Msgbus_Data *_e_msgbus_data = NULL; +static const Eldbus_Service_Interface_Desc _screensaver_core_desc = { + SCREENSAVER_IFACE, _screensaver_core_methods, NULL, NULL, NULL, NULL +}; +/////////////////////////////////////////////////////////////////////////// + +E_API E_Msgbus_Data *e_msgbus_data = NULL; /* externally accessible functions */ EINTERN int e_msgbus_init(void) { - _e_msgbus_data = E_NEW(E_Msgbus_Data, 1); + e_msgbus_data = E_NEW(E_Msgbus_Data, 1); eldbus_init(); - _e_msgbus_data->conn = eldbus_connection_get(ELDBUS_CONNECTION_TYPE_SESSION); - if (!_e_msgbus_data->conn) + e_msgbus_data->conn = eldbus_connection_get(ELDBUS_CONNECTION_TYPE_SESSION); + if (!e_msgbus_data->conn) { WRN("Cannot get ELDBUS_CONNECTION_TYPE_SESSION"); return 0; } - _e_msgbus_data->e_iface = eldbus_service_interface_register - (_e_msgbus_data->conn, E_PATH, &core_desc); - eldbus_name_request(_e_msgbus_data->conn, E_BUS, 0, - _e_msgbus_request_name_cb, NULL); + e_msgbus_data->e_iface = eldbus_service_interface_register + (e_msgbus_data->conn, E_PATH, &_e_core_desc); + eldbus_name_request(e_msgbus_data->conn, E_BUS, 0, + _e_msgbus_core_request_name_cb, NULL); + + e_msgbus_data->screensaver_iface = eldbus_service_interface_register + (e_msgbus_data->conn, SCREENSAVER_PATH, &_screensaver_core_desc); + eldbus_name_request(e_msgbus_data->conn, SCREENSAVER_BUS, 0, + _e_msgbus_screensaver_request_name_cb, NULL); return 1; } EINTERN int e_msgbus_shutdown(void) { - if (_e_msgbus_data->e_iface) - eldbus_service_object_unregister(_e_msgbus_data->e_iface); - if (_e_msgbus_data->conn) + E_Msgbus_Data_Screensaver_Inhibit *inhibit; + + if (e_msgbus_data->e_iface) + eldbus_service_object_unregister(e_msgbus_data->e_iface); + if (e_msgbus_data->conn) { - eldbus_name_release(_e_msgbus_data->conn, E_BUS, NULL, NULL); - eldbus_connection_unref(_e_msgbus_data->conn); + eldbus_name_release(e_msgbus_data->conn, E_BUS, NULL, NULL); + eldbus_connection_unref(e_msgbus_data->conn); } eldbus_shutdown(); - E_FREE(_e_msgbus_data); + EINA_LIST_FREE(e_msgbus_data->screensaver_inhibits, inhibit) + _e_msgbus_screensaver_inhibit_free(inhibit); + + E_FREE(e_msgbus_data); return 1; } E_API Eldbus_Service_Interface * e_msgbus_interface_attach(const Eldbus_Service_Interface_Desc *desc) { - if (!_e_msgbus_data->e_iface) return NULL; - return eldbus_service_interface_register(_e_msgbus_data->conn, E_PATH, desc); + if (!e_msgbus_data->e_iface) return NULL; + return eldbus_service_interface_register(e_msgbus_data->conn, E_PATH, desc); } +/////////////////////////////////////////////////////////////////////////// static void -_e_msgbus_request_name_cb(void *data EINA_UNUSED, const Eldbus_Message *msg, - Eldbus_Pending *pending EINA_UNUSED) +_e_msgbus_core_request_name_cb(void *data EINA_UNUSED, + const Eldbus_Message *msg, + Eldbus_Pending *pending EINA_UNUSED) { unsigned int flag; @@ -87,10 +121,9 @@ _e_msgbus_request_name_cb(void *data EINA_UNUSED, const Eldbus_Message *msg, return; } if (!(flag & ELDBUS_NAME_REQUEST_REPLY_PRIMARY_OWNER)) - WRN("Name already in use\n"); + WRN("Enlightenment core name already in use\n"); } -/* Core Handlers */ static Eldbus_Message * _e_msgbus_core_version_cb(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg) @@ -123,3 +156,171 @@ _e_msgbus_core_shutdown_cb(const Eldbus_Service_Interface *iface EINA_UNUSED, e_sys_action_do(E_SYS_EXIT, NULL); return eldbus_message_method_return_new(msg); } +/////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////// +static void +_e_msgbus_screensaver_request_name_cb(void *data EINA_UNUSED, + const Eldbus_Message *msg, + Eldbus_Pending *pending EINA_UNUSED) +{ + unsigned int flag; + + if (eldbus_message_error_get(msg, NULL, NULL)) + { + ERR("Could not request bus name"); + return; + } + if (!eldbus_message_arguments_get(msg, "u", &flag)) + { + ERR("Could not get arguments on on_name_request"); + return; + } + if (!(flag & ELDBUS_NAME_REQUEST_REPLY_PRIMARY_OWNER)) + WRN("Screensaver name already in use\n"); +} + +static void +_e_msgbus_screensaver_inhibit_free(E_Msgbus_Data_Screensaver_Inhibit *inhibit) +{ + printf("INH: inhibit remove %i [%s] [%s] [%s]\n", inhibit->cookie, inhibit->application, inhibit->reason, inhibit->sender); + if (inhibit->application) eina_stringshare_del(inhibit->application); + if (inhibit->reason) eina_stringshare_del(inhibit->reason); + if (inhibit->sender) + { + eldbus_name_owner_changed_callback_del(e_msgbus_data->conn, + inhibit->sender, + _e_msgbus_screensaver_owner_change_cb, + NULL); + eina_stringshare_del(inhibit->sender); + } + free(inhibit); +} + +static void +_e_msgbus_screensaver_owner_change_cb(void *data EINA_UNUSED, const char *bus EINA_UNUSED, const char *old_id, const char *new_id) +{ + Eina_List *l, *ll; + E_Msgbus_Data_Screensaver_Inhibit *inhibit; + Eina_Bool removed = EINA_FALSE; + + printf("INH: owner change... [%s] [%s] [%s]\n", bus, old_id, new_id); + if ((new_id) && (!new_id[0])) + { + EINA_LIST_FOREACH_SAFE(e_msgbus_data->screensaver_inhibits, l, ll, inhibit) + { + if ((inhibit->sender) && (!strcmp(inhibit->sender, old_id))) + { + _e_msgbus_screensaver_inhibit_free(inhibit); + e_msgbus_data->screensaver_inhibits = + eina_list_remove_list + (e_msgbus_data->screensaver_inhibits, l); + removed = EINA_TRUE; + } + } + if ((removed) && (!e_msgbus_data->screensaver_inhibits)) + { + // stop inhibiting SS + e_screensaver_update(); + } + } +} + +static Eldbus_Message * +_e_msgbus_screensaver_inhibit_cb(const Eldbus_Service_Interface *iface EINA_UNUSED, + const Eldbus_Message *msg) +{ + Eldbus_Message *reply = NULL; + static unsigned int cookie = 1; + const char *application_name = NULL, *reason_for_inhibit = NULL; + E_Msgbus_Data_Screensaver_Inhibit *inhibit; + + if (!eldbus_message_arguments_get(msg, "ss", + &application_name, &reason_for_inhibit)) + { + ERR("Can't get application_name and reason_for_inhibit"); + goto err; + } + inhibit = E_NEW(E_Msgbus_Data_Screensaver_Inhibit, 1); + if (inhibit) + { + cookie++; + inhibit->application = eina_stringshare_add(application_name); + inhibit->reason = eina_stringshare_add(reason_for_inhibit); + inhibit->sender = eina_stringshare_add(eldbus_message_sender_get(msg)); + if (inhibit->sender) + eldbus_name_owner_changed_callback_add(e_msgbus_data->conn, + inhibit->sender, + _e_msgbus_screensaver_owner_change_cb, + NULL, EINA_FALSE); + inhibit->cookie = cookie; + printf("INH: inhibit [%s] [%s] [%s] -> %i\n", inhibit->application, inhibit->reason, inhibit->sender, inhibit->cookie); + e_msgbus_data->screensaver_inhibits = + eina_list_append(e_msgbus_data->screensaver_inhibits, inhibit); + reply = eldbus_message_method_return_new(msg); + if (reply) + eldbus_message_arguments_append(reply, "u", inhibit->cookie); + } + if ((e_msgbus_data->screensaver_inhibits) && + (eina_list_count(e_msgbus_data->screensaver_inhibits) == 1)) + { + // start inhibiting SS + e_screensaver_deactivate(); + e_screensaver_update(); + } +err: + return reply; +} + +static Eldbus_Message * +_e_msgbus_screensaver_uninhibit_cb(const Eldbus_Service_Interface *iface EINA_UNUSED, + const Eldbus_Message *msg) +{ + unsigned int cookie = 0; + + if (!eldbus_message_arguments_get(msg, "u", &cookie)) + return NULL; + e_msgbus_screensaver_inhibit_remove(cookie); + return eldbus_message_method_return_new(msg); +} + +static Eldbus_Message * +_e_msgbus_screensaver_getactive_cb(const Eldbus_Service_Interface *iface EINA_UNUSED, + const Eldbus_Message *msg) +{ + Eldbus_Message *reply = NULL; + + reply = eldbus_message_method_return_new(msg); + printf("INH: getactive = %i\n", e_screensaver_on_get()); + if (reply) + eldbus_message_arguments_append(reply, "b", e_screensaver_on_get()); + return reply; +} + +E_API void +e_msgbus_screensaver_inhibit_remove(unsigned int cookie) +{ + Eina_Bool removed = EINA_FALSE; + Eina_List *l; + E_Msgbus_Data_Screensaver_Inhibit *inhibit; + + EINA_LIST_FOREACH(e_msgbus_data->screensaver_inhibits, l, inhibit) + { + if (inhibit->cookie == cookie) + { + _e_msgbus_screensaver_inhibit_free(inhibit); + e_msgbus_data->screensaver_inhibits = + eina_list_remove_list + (e_msgbus_data->screensaver_inhibits, l); + removed = EINA_TRUE; + break; + } + } + if ((removed) && (!e_msgbus_data->screensaver_inhibits)) + { + // stop inhibiting SS + e_screensaver_update(); + } +} + +/////////////////////////////////////////////////////////////////////////// diff --git a/src/bin/e_msgbus.h b/src/bin/e_msgbus.h index 5af8b3d23..8be049f82 100644 --- a/src/bin/e_msgbus.h +++ b/src/bin/e_msgbus.h @@ -1,6 +1,7 @@ #ifdef E_TYPEDEFS -typedef struct _E_Msgbus_Data E_Msgbus_Data; +typedef struct _E_Msgbus_Data E_Msgbus_Data; +typedef struct _E_Msgbus_Data_Screensaver_Inhibit E_Msgbus_Data_Screensaver_Inhibit; #else #ifndef E_MSGBUS_H @@ -11,12 +12,25 @@ typedef struct _E_Msgbus_Data E_Msgbus_Data; struct _E_Msgbus_Data { Eldbus_Connection *conn; - Eldbus_Service_Interface *iface; + Eldbus_Service_Interface *e_iface; + Eldbus_Service_Interface *screensaver_iface; + Eina_List *screensaver_inhibits; +}; + +struct _E_Msgbus_Data_Screensaver_Inhibit +{ + const char *application; + const char *reason; + const char *sender; + unsigned int cookie; }; EINTERN int e_msgbus_init(void); EINTERN int e_msgbus_shutdown(void); E_API Eldbus_Service_Interface *e_msgbus_interface_attach(const Eldbus_Service_Interface_Desc *desc); +E_API void e_msgbus_screensaver_inhibit_remove(unsigned int cookie); + +E_API extern E_Msgbus_Data *e_msgbus_data; #endif #endif diff --git a/src/bin/e_screensaver.c b/src/bin/e_screensaver.c index 9f260e6ad..96dde1eb9 100644 --- a/src/bin/e_screensaver.c +++ b/src/bin/e_screensaver.c @@ -114,6 +114,10 @@ e_screensaver_update(void) (!((e_util_fullscreen_current_any()) && (e_config->no_dpms_on_fullscreen))))) timeout = 0; + if (e_msgbus_data) + { + if (e_msgbus_data->screensaver_inhibits) timeout = 0; + } if (_e_screensaver_timeout != timeout) {