6 #include <dbus/dbus-glib.h>
7 #include <dbus/dbus-glib-lowlevel.h>
8 #include <hal/libhal.h>
11 #include <mce/dbus-names.h>
12 #include <mce/mode-names.h>
14 #define HAL_COND_BUTTONPRESSED "ButtonPressed"
15 #define HAL_BUTTON_POWER "power"
16 #define HAL_INPUTDEV_PATH "/org/freedesktop/Hal/devices/computer_logicaldev_input"
29 static void speak_time(struct app_data *app)
31 struct espeaktime_settings cfg;
32 cfg_read(app->gconf, &cfg);
33 cfg_speak(&cfg, FALSE);
37 static void sig_tklock_mode(DBusGProxy *proxy, const char *mode, gpointer user_data)
39 struct app_data *app = user_data;
40 g_debug("sig_tklock_mode [%s]", mode);
41 app->mode_locked = !strcmp(mode, MCE_TK_LOCKED);
44 static void sig_display_status(DBusGProxy *proxy, const char *status, gpointer user_data)
46 struct app_data *app = user_data;
47 g_debug("sig_display_status [%s]", status);
48 app->display_on = !strcmp(status, MCE_DISPLAY_ON_STRING);
50 /* Double-pressing the button at a normal rate will usually result
51 * in the two ButtonPress events being received before the display_status==on
52 * event. Check here if that's the case.
54 if (app->mode_locked && app->display_on && app->press_count > 1 &&
55 time(NULL) - app->last_press <= 1)
59 static void debug_log(const gchar *log_domain,
60 GLogLevelFlags log_level, const gchar *message, gpointer unused_data)
62 g_print("# %s\n", message);
65 static void power_button(struct app_data *app)
70 if (now - app->last_press > 1)
73 app->last_press = now;
75 g_debug("power button: count=%d", app->press_count);
76 if (app->mode_locked && app->display_on)
81 * Call a method with no input arguments and one string output argument.
82 * Return the allocaed result string on success, NULL on failure.
84 static char *mce_call_getstr(DBusGProxy *proxy, const char *method)
89 if (dbus_g_proxy_call(proxy, method, &err,
91 G_TYPE_STRING, &s, G_TYPE_INVALID))
94 g_error("Couldn't call MCE (%s): %s\n", method, err->message);
99 static gboolean prefill_status(struct app_data *app)
104 mce_req = dbus_g_proxy_new_for_name(app->bus, MCE_SERVICE, MCE_REQUEST_PATH, MCE_REQUEST_IF);
107 mode = mce_call_getstr(mce_req, MCE_TKLOCK_MODE_GET);
108 status = mce_call_getstr(mce_req, MCE_DISPLAY_STATUS_GET);
110 sig_tklock_mode(NULL, mode, app);
112 sig_display_status(NULL, status, app);
115 g_object_unref(mce_req);
117 return mode && status;
120 static void connect_signals(struct app_data *app)
124 mce_sig = dbus_g_proxy_new_for_name(app->bus, MCE_SERVICE, MCE_SIGNAL_PATH, MCE_SIGNAL_IF);
126 dbus_g_proxy_add_signal(mce_sig, MCE_TKLOCK_MODE_SIG, G_TYPE_STRING, G_TYPE_INVALID);
127 dbus_g_proxy_add_signal(mce_sig, MCE_DISPLAY_SIG, G_TYPE_STRING, G_TYPE_INVALID);
128 dbus_g_proxy_connect_signal(mce_sig, MCE_TKLOCK_MODE_SIG, G_CALLBACK(sig_tklock_mode), app, NULL);
129 dbus_g_proxy_connect_signal(mce_sig, MCE_DISPLAY_SIG, G_CALLBACK(sig_display_status), app, NULL);
133 static void device_condition(LibHalContext *ctx,
135 const char *condition_name,
136 const char *condition_detail)
138 g_debug("device_condition: name [%s] detail [%s]",
139 condition_name, condition_detail);
140 if (!strcmp(condition_name, HAL_COND_BUTTONPRESSED) && !strcmp(condition_detail, HAL_BUTTON_POWER)) {
141 struct app_data *app = libhal_ctx_get_user_data(ctx);
147 static gboolean init_hal(struct app_data *app)
151 app->hal = libhal_ctx_new();
153 g_error("Couldn't get a HAL context");
156 libhal_ctx_set_dbus_connection(app->hal,
157 dbus_g_connection_get_connection(app->bus));
158 libhal_ctx_set_device_condition(app->hal, device_condition);
159 libhal_ctx_set_user_data(app->hal, app);
161 dbus_error_init(&err);
162 if (!libhal_ctx_init(app->hal, &err)) {
163 g_error("Couldn't initialize HAL context: %s", err.message);
164 dbus_error_free(&err);
165 libhal_ctx_free(app->hal);
169 if (!libhal_device_add_property_watch(app->hal, HAL_INPUTDEV_PATH, &err)) {
170 g_error("Couldn't add HAL watch: %s", err.message);
171 dbus_error_free(&err);
172 libhal_ctx_free(app->hal);
177 int main(int argc, char *argv[])
183 if (argc > 1 && !strcmp(argv[1], "-v"))
184 g_log_set_handler(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, debug_log, NULL);
187 memset(&app, 0, sizeof(app));
188 signal(SIGCHLD, SIG_IGN);
191 loop = g_main_loop_new(NULL, FALSE);
193 app.bus = dbus_g_bus_get(DBUS_BUS_SYSTEM, &err);
195 g_error("Couldn't get DBUS connection: %s\n", err->message);
200 app.gconf = gconf_client_get_default();
206 if (!prefill_status(&app))
208 connect_signals(&app);
211 g_main_loop_run(loop);
212 dbus_g_connection_unref(app.bus);