2 * Flashlight applet (widget) for Maemo.
3 * Copyright (C) 2009, 2010 Roman Moravcik
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 #include <hildon/hildon.h>
29 #include <glib/gi18n-lib.h>
31 #include <dbus/dbus.h>
33 #include "flashlight_applet.h"
34 #include "flashlight_lib.h"
36 #define MSG_FLASHLIGHT_ON _("On")
37 #define MSG_FLASHLIGHT_OFF _("Off")
39 #define ICON_FLASHLIGHT_ON "statusarea_flashlight_on"
40 #define ICON_FLASHLIGHT_OFF "statusarea_flashlight_off"
42 #define CAM_COVER_UDI "/org/freedesktop/Hal/devices/platform_cam_shutter"
43 #define CAM_COVER_STATE "button.state.value"
45 #define FLASHLIGHT_STATUS_PLUGIN_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE (obj, \
46 TYPE_FLASHLIGHT_STATUS_PLUGIN, FlashlightPluginPrivate))
48 struct _FlashlightPluginPrivate
53 FlashlightContext_t *flashlight;
54 DBusConnection *dbus_connection;
58 HD_DEFINE_PLUGIN_MODULE (FlashlightPlugin, flashlight_status_plugin, HD_TYPE_STATUS_MENU_ITEM)
60 static gboolean flashlight_status_plugin_status (gpointer data);
61 static void flashlight_status_plugin_finalize (GObject *object);
64 flashlight_status_plugin_show_notification (FlashlightPlugin *plugin,
67 FlashlightPluginPrivate *priv = FLASHLIGHT_STATUS_PLUGIN_GET_PRIVATE (plugin);
70 g_return_if_fail (priv);
71 g_return_if_fail (priv->button);
73 banner = hildon_banner_show_information (GTK_WIDGET (priv->button), NULL, text);
74 hildon_banner_set_timeout (HILDON_BANNER (banner), 3000);
78 flashlight_status_plugin_enable (FlashlightPlugin *plugin,
81 FlashlightPluginPrivate *priv = FLASHLIGHT_STATUS_PLUGIN_GET_PRIVATE (plugin);
83 g_return_if_fail (priv);
84 g_return_if_fail (priv->button);
87 if (flashlight_open (priv->flashlight, "/dev/video0") < 0) {
88 flashlight_status_plugin_show_notification (plugin,
89 _("Unable to initialize flashlight.\nCamera in use by another application."));
90 flashlight_close (priv->flashlight);
94 if (flashlight_set_intensity (priv->flashlight, 1) < 0) {
95 flashlight_status_plugin_show_notification (plugin,
96 _("Unable to turn on flashlight."));
97 flashlight_close (priv->flashlight);
101 hildon_button_set_value (HILDON_BUTTON (priv->button), MSG_FLASHLIGHT_ON);
102 hildon_button_set_image (HILDON_BUTTON (priv->button),
103 gtk_image_new_from_icon_name (ICON_FLASHLIGHT_ON, -1));
105 /* check status of controller every 1s */
106 priv->status_timer = g_timeout_add (1000, flashlight_status_plugin_status, plugin);
108 /* cancel status timer */
109 if (priv->status_timer) {
110 g_source_remove (priv->status_timer);
111 priv->status_timer = 0;
114 /* set intensity to 0 */
115 if (flashlight_set_intensity (priv->flashlight, 0) < 0) {
116 flashlight_status_plugin_show_notification (plugin,
117 _("Unable to turn off flashlight."));
121 if (flashlight_close (priv->flashlight) < 0) {
125 hildon_button_set_value (HILDON_BUTTON (priv->button), MSG_FLASHLIGHT_OFF);
126 hildon_button_set_image (HILDON_BUTTON (priv->button),
127 gtk_image_new_from_icon_name (ICON_FLASHLIGHT_OFF, -1));
132 flashlight_status_plugin_on_hal_property_modified (LibHalContext *ctx,
135 dbus_bool_t is_removed,
136 dbus_bool_t is_added)
138 FlashlightPlugin *plugin = libhal_ctx_get_user_data (ctx);
139 FlashlightPluginPrivate *priv = FLASHLIGHT_STATUS_PLUGIN_GET_PRIVATE (plugin);
140 gboolean is_open = FALSE;
143 g_return_if_fail (priv);
145 if (strcmp (udi, CAM_COVER_UDI) != 0)
148 if (strcmp (key, CAM_COVER_STATE) != 0)
151 is_open = !libhal_device_get_property_bool (ctx, udi, key, NULL);
155 gtk_widget_show_all (GTK_WIDGET (plugin));
157 /* turn off flashlight if flashlight is enabled */
158 if (flashlight_get_intensity (priv->flashlight, &intensity) == 0) {
160 flashlight_status_plugin_enable (plugin, FALSE);
165 gtk_widget_hide_all (GTK_WIDGET (plugin));
170 flashlight_status_plugin_status (gpointer data)
172 FlashlightPlugin *plugin = data;
173 FlashlightPluginPrivate *priv = FLASHLIGHT_STATUS_PLUGIN_GET_PRIVATE (plugin);
176 if (flashlight_get_status (priv->flashlight, &status) < 0) {
177 flashlight_status_plugin_show_notification (plugin,
178 _("Unable to read status from driver."));
182 /* ops, something is wrong */
184 /* turn off flashlight */
185 flashlight_status_plugin_enable (plugin, FALSE);
187 if (status & FLASHLIGHT_STATUS_SHORT_CIRCUT_FAULT) {
188 flashlight_status_plugin_show_notification (plugin,
189 _("Short-circut fault detected!\nTurning off flashlight."));
190 } else if (status & FLASHLIGHT_STATUS_OVERTEMPERATURE_FAULT) {
191 flashlight_status_plugin_show_notification (plugin,
192 _("Overtemperature fault detected!\nTurning off flashlight."));
193 } else if (status & FLASHLIGHT_STATUS_TIMEOUT_FAULT) {
194 flashlight_status_plugin_show_notification (plugin,
195 _("Timeout fault detected!\nTurning off flashlight."));
196 } else if (status & FLASHLIGHT_STATUS_OVERVOLTAGE_FAULT) {
197 flashlight_status_plugin_show_notification (plugin,
198 _("Overvoltage fault detected!\nTurning off flashlight."));
206 flashlight_status_plugin_on_clicked (HildonButton *button,
209 FlashlightPlugin *plugin = data;
210 FlashlightPluginPrivate *priv = FLASHLIGHT_STATUS_PLUGIN_GET_PRIVATE (plugin);
212 g_return_if_fail (priv);
214 if (!strcmp (hildon_button_get_value (button), MSG_FLASHLIGHT_ON)) {
215 flashlight_status_plugin_enable (plugin, FALSE);
217 flashlight_status_plugin_enable (plugin, TRUE);
222 flashlight_status_plugin_ui (FlashlightPlugin *plugin)
226 g_return_val_if_fail (plugin, NULL);
228 button = hildon_button_new (HILDON_SIZE_FINGER_HEIGHT, HILDON_BUTTON_ARRANGEMENT_VERTICAL);
229 gtk_button_set_alignment (GTK_BUTTON (button), 0.0, 0.5);
230 hildon_button_set_title (HILDON_BUTTON (button), _("Flashlight"));
231 hildon_button_set_value (HILDON_BUTTON (button), MSG_FLASHLIGHT_OFF);
232 hildon_button_set_image (HILDON_BUTTON (button),
233 gtk_image_new_from_icon_name (ICON_FLASHLIGHT_OFF, -1));
234 hildon_button_set_image_position (HILDON_BUTTON (button), GTK_POS_LEFT);
236 g_signal_connect (button, "clicked",
237 G_CALLBACK (flashlight_status_plugin_on_clicked), plugin);
243 flashlight_status_plugin_class_init (FlashlightPluginClass *class)
245 GObjectClass *object_class = G_OBJECT_CLASS (class);
247 object_class->finalize = flashlight_status_plugin_finalize;
249 g_type_class_add_private (class, sizeof (FlashlightPluginPrivate));
253 flashlight_status_plugin_class_finalize (FlashlightPluginClass *class)
258 flashlight_status_plugin_init (FlashlightPlugin *plugin)
260 FlashlightPluginPrivate *priv = FLASHLIGHT_STATUS_PLUGIN_GET_PRIVATE (plugin);
263 /* initialize dbus */
264 dbus_error_init (&error);
265 priv->dbus_connection = dbus_bus_get (DBUS_BUS_SYSTEM, &error);
266 if (dbus_error_is_set (&error)) {
267 g_critical ("flashlight_status_plugin_init: Could not get the system DBus connection, %s",
269 dbus_error_free (&error);
273 /* initialize flashlight */
274 if (flashlight_init (&priv->flashlight) < 0) {
275 g_critical ("flashlight_status_plugin_init: Unable to create Flashlight context\n");
280 priv->hal = libhal_ctx_new ();
282 g_critical ("flashlight_status_plugin_init: Unable to create HAL context\n");
286 libhal_ctx_set_dbus_connection (priv->hal, priv->dbus_connection);
287 libhal_ctx_set_user_data (priv->hal, plugin);
288 libhal_ctx_set_device_property_modified (priv->hal,
289 flashlight_status_plugin_on_hal_property_modified);
291 if (!libhal_ctx_init (priv->hal, &error)) {
292 if (dbus_error_is_set (&error)) {
293 g_critical ("Could not initialize the HAL context, %s",
295 dbus_error_free (&error);
297 g_critical ("Could not initialize the HAL context, "
298 "no error, is hald running?");
300 libhal_ctx_set_user_data (priv->hal, NULL);
301 libhal_ctx_free (priv->hal);
306 libhal_device_add_property_watch (priv->hal, CAM_COVER_UDI, NULL);
308 /* create plugin ui */
309 priv->button = flashlight_status_plugin_ui (plugin);
310 gtk_container_add (GTK_CONTAINER (plugin), priv->button);
312 /* show widget if camera cover is open */
313 if ( !libhal_device_get_property_bool (priv->hal, CAM_COVER_UDI, CAM_COVER_STATE, NULL))
314 gtk_widget_show_all (GTK_WIDGET (plugin));
319 flashlight_status_plugin_finalize (GObject *object)
321 FlashlightPlugin *plugin = FLASHLIGHT_STATUS_PLUGIN (object);
322 FlashlightPluginPrivate *priv = FLASHLIGHT_STATUS_PLUGIN_GET_PRIVATE (plugin);
324 g_return_if_fail (priv);
326 /* deinitialize hal */
328 libhal_device_remove_property_watch (priv->hal, CAM_COVER_UDI, NULL);
329 libhal_ctx_set_user_data (priv->hal, NULL);
330 libhal_ctx_shutdown (priv->hal, NULL);
331 libhal_ctx_free (priv->hal);
335 /* unreference dbus connection */
336 if (priv->dbus_connection) {
337 dbus_connection_unref (priv->dbus_connection);
339 priv->dbus_connection = NULL;
341 /* cancel status timer */
342 if (priv->status_timer) {
343 g_source_remove (priv->status_timer);
345 priv->status_timer = 0;
347 /* deinitialize flashlight */
348 if (priv->flashlight) {
349 flashlight_deinit (priv->flashlight);
351 priv->flashlight = NULL;
353 G_OBJECT_CLASS (flashlight_status_plugin_parent_class)->finalize (object);