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>
35 #include "flashlight_applet.h"
36 #include "flashlight_lib.h"
38 #define MSG_FLASHLIGHT_ON _("On")
39 #define MSG_FLASHLIGHT_OFF _("Off")
41 #define ICON_FLASHLIGHT_ON "statusarea_flashlight_on"
42 #define ICON_FLASHLIGHT_OFF "statusarea_flashlight_off"
44 #define CAM_COVER_UDI "/org/freedesktop/Hal/devices/platform_cam_shutter"
45 #define CAM_COVER_STATE "button.state.value"
47 #define FLASHLIGHT_APPLET_SERVICE "org.maemo.flashlight_applet"
48 #define FLASHLIGHT_APPLET_OBJECT "/org/maemo/flashlight_applet"
49 #define FLASHLIGHT_APPLET_IFACE "org.maemo.flashlight_applet"
51 #define FLASHLIGHT_APPLET_METHOD_ENABLE "enable"
52 #define FLASHLIGHT_APPLET_METHOD_DISABLE "disable"
54 #define _CAMERAUI(str) dgettext("osso-camera-ui",str)
56 #define FLASHLIGHT_STATUS_PLUGIN_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE (obj, \
57 TYPE_FLASHLIGHT_STATUS_PLUGIN, FlashlightPluginPrivate))
59 struct _FlashlightPluginPrivate
64 FlashlightContext_t *flashlight;
65 DBusConnection *dbus_connection;
67 osso_context_t *osso_context;
70 HD_DEFINE_PLUGIN_MODULE (FlashlightPlugin, flashlight_status_plugin, HD_TYPE_STATUS_MENU_ITEM)
72 static gboolean flashlight_status_plugin_status (gpointer data);
73 static void flashlight_status_plugin_finalize (GObject *object);
76 flashlight_status_plugin_show_notification (FlashlightPlugin *plugin,
79 FlashlightPluginPrivate *priv = FLASHLIGHT_STATUS_PLUGIN_GET_PRIVATE (plugin);
82 g_return_if_fail (priv);
83 g_return_if_fail (priv->button);
85 banner = hildon_banner_show_information (GTK_WIDGET (priv->button), NULL, text);
86 hildon_banner_set_timeout (HILDON_BANNER (banner), 3000);
90 flashlight_status_plugin_enable (FlashlightPlugin *plugin,
93 FlashlightPluginPrivate *priv = FLASHLIGHT_STATUS_PLUGIN_GET_PRIVATE (plugin);
95 g_return_if_fail (priv);
96 g_return_if_fail (priv->button);
99 if (flashlight_open (priv->flashlight, "/dev/video0") < 0) {
100 flashlight_status_plugin_show_notification (plugin,
101 _("Unable to initialize flashlight.\nCamera in use by another application."));
102 flashlight_close (priv->flashlight);
106 if (flashlight_set_intensity (priv->flashlight, 1) < 0) {
107 flashlight_status_plugin_show_notification (plugin,
108 _("Unable to turn on flashlight."));
109 flashlight_close (priv->flashlight);
113 hildon_button_set_value (HILDON_BUTTON (priv->button), MSG_FLASHLIGHT_ON);
114 hildon_button_set_image (HILDON_BUTTON (priv->button),
115 gtk_image_new_from_icon_name (ICON_FLASHLIGHT_ON, -1));
117 /* check status of controller every 1s */
118 priv->status_timer = g_timeout_add (1000, flashlight_status_plugin_status, plugin);
120 /* cancel status timer */
121 if (priv->status_timer) {
122 g_source_remove (priv->status_timer);
123 priv->status_timer = 0;
126 /* set intensity to 0 */
127 if (flashlight_set_intensity (priv->flashlight, 0) < 0) {
128 flashlight_status_plugin_show_notification (plugin,
129 _("Unable to turn off flashlight."));
133 if (flashlight_close (priv->flashlight) < 0) {
137 hildon_button_set_value (HILDON_BUTTON (priv->button), MSG_FLASHLIGHT_OFF);
138 hildon_button_set_image (HILDON_BUTTON (priv->button),
139 gtk_image_new_from_icon_name (ICON_FLASHLIGHT_OFF, -1));
144 flashlight_applet_dbus_request_handler (const gchar *interface,
150 FlashlightPlugin *plugin = data;
151 FlashlightPluginPrivate *priv = FLASHLIGHT_STATUS_PLUGIN_GET_PRIVATE (plugin);
152 gboolean is_open = FALSE;
154 g_return_val_if_fail (interface, OSSO_ERROR);
155 g_return_val_if_fail (method, OSSO_ERROR);
157 g_return_val_if_fail (priv, OSSO_ERROR);
158 g_return_val_if_fail (priv->hal, OSSO_ERROR);
159 g_return_val_if_fail (priv->button, OSSO_ERROR);
161 if (strcmp (interface, FLASHLIGHT_APPLET_IFACE))
164 is_open = !libhal_device_get_property_bool (priv->hal, CAM_COVER_UDI, CAM_COVER_STATE, NULL);
166 if (!strcmp (method, FLASHLIGHT_APPLET_METHOD_ENABLE)) {
167 /* check if cover is open */
169 /* try to enable flashlight, only if it's disabled */
170 if (!strcmp (hildon_button_get_value (HILDON_BUTTON (priv->button)), MSG_FLASHLIGHT_OFF)) {
171 flashlight_status_plugin_enable (plugin, TRUE);
174 flashlight_status_plugin_show_notification (plugin, _CAMERAUI ("camera_ia_open_lens_cover"));
176 } else if (!strcmp (method, FLASHLIGHT_APPLET_METHOD_DISABLE)) {
178 /* try to disable flashlight, only if it's enabled */
179 if (!strcmp (hildon_button_get_value (HILDON_BUTTON (priv->button)), MSG_FLASHLIGHT_ON)) {
180 flashlight_status_plugin_enable (plugin, FALSE);
191 flashlight_status_plugin_on_hal_property_modified (LibHalContext *ctx,
194 dbus_bool_t is_removed,
195 dbus_bool_t is_added)
197 FlashlightPlugin *plugin = libhal_ctx_get_user_data (ctx);
198 FlashlightPluginPrivate *priv = FLASHLIGHT_STATUS_PLUGIN_GET_PRIVATE (plugin);
199 gboolean is_open = FALSE;
202 g_return_if_fail (priv);
204 if (strcmp (udi, CAM_COVER_UDI) != 0)
207 if (strcmp (key, CAM_COVER_STATE) != 0)
210 is_open = !libhal_device_get_property_bool (ctx, udi, key, NULL);
214 gtk_widget_show_all (GTK_WIDGET (plugin));
216 /* turn off flashlight if flashlight is enabled */
217 if (flashlight_get_intensity (priv->flashlight, &intensity) == 0) {
219 flashlight_status_plugin_enable (plugin, FALSE);
224 gtk_widget_hide_all (GTK_WIDGET (plugin));
229 flashlight_status_plugin_status (gpointer data)
231 FlashlightPlugin *plugin = data;
232 FlashlightPluginPrivate *priv = FLASHLIGHT_STATUS_PLUGIN_GET_PRIVATE (plugin);
235 if (flashlight_get_status (priv->flashlight, &status) < 0) {
236 flashlight_status_plugin_show_notification (plugin,
237 _("Unable to read status from driver."));
241 /* ops, something is wrong */
243 /* turn off flashlight */
244 flashlight_status_plugin_enable (plugin, FALSE);
246 if (status & FLASHLIGHT_STATUS_SHORT_CIRCUT_FAULT) {
247 flashlight_status_plugin_show_notification (plugin,
248 _("Short-circut fault detected!\nTurning off flashlight."));
249 } else if (status & FLASHLIGHT_STATUS_OVERTEMPERATURE_FAULT) {
250 flashlight_status_plugin_show_notification (plugin,
251 _("Overtemperature fault detected!\nTurning off flashlight."));
252 } else if (status & FLASHLIGHT_STATUS_TIMEOUT_FAULT) {
253 flashlight_status_plugin_show_notification (plugin,
254 _("Timeout fault detected!\nTurning off flashlight."));
255 } else if (status & FLASHLIGHT_STATUS_OVERVOLTAGE_FAULT) {
256 flashlight_status_plugin_show_notification (plugin,
257 _("Overvoltage fault detected!\nTurning off flashlight."));
265 flashlight_status_plugin_on_clicked (HildonButton *button,
268 FlashlightPlugin *plugin = data;
269 FlashlightPluginPrivate *priv = FLASHLIGHT_STATUS_PLUGIN_GET_PRIVATE (plugin);
271 g_return_if_fail (priv);
273 if (!strcmp (hildon_button_get_value (button), MSG_FLASHLIGHT_ON)) {
274 flashlight_status_plugin_enable (plugin, FALSE);
276 flashlight_status_plugin_enable (plugin, TRUE);
281 flashlight_status_plugin_ui (FlashlightPlugin *plugin)
285 g_return_val_if_fail (plugin, NULL);
287 button = hildon_button_new (HILDON_SIZE_FINGER_HEIGHT, HILDON_BUTTON_ARRANGEMENT_VERTICAL);
288 gtk_button_set_alignment (GTK_BUTTON (button), 0.0, 0.5);
289 hildon_button_set_style (HILDON_BUTTON (button), HILDON_BUTTON_STYLE_PICKER);
290 hildon_button_set_title (HILDON_BUTTON (button), _("Flashlight"));
291 hildon_button_set_value (HILDON_BUTTON (button), MSG_FLASHLIGHT_OFF);
292 hildon_button_set_image (HILDON_BUTTON (button),
293 gtk_image_new_from_icon_name (ICON_FLASHLIGHT_OFF, -1));
294 hildon_button_set_image_position (HILDON_BUTTON (button), GTK_POS_LEFT);
296 g_signal_connect (button, "clicked",
297 G_CALLBACK (flashlight_status_plugin_on_clicked), plugin);
303 flashlight_status_plugin_class_init (FlashlightPluginClass *class)
305 GObjectClass *object_class = G_OBJECT_CLASS (class);
307 object_class->finalize = flashlight_status_plugin_finalize;
309 g_type_class_add_private (class, sizeof (FlashlightPluginPrivate));
313 flashlight_status_plugin_class_finalize (FlashlightPluginClass *class)
318 flashlight_status_plugin_init (FlashlightPlugin *plugin)
320 FlashlightPluginPrivate *priv = FLASHLIGHT_STATUS_PLUGIN_GET_PRIVATE (plugin);
323 /* initialize osso */
324 priv->osso_context = osso_initialize (PACKAGE, VERSION, TRUE, NULL);
325 if (!priv->osso_context) {
326 g_critical ("flashlight_status_plugin_init: Could not initialize OSSO\n");
330 if (osso_rpc_set_cb_f (priv->osso_context,
331 FLASHLIGHT_APPLET_SERVICE,
332 FLASHLIGHT_APPLET_OBJECT,
333 FLASHLIGHT_APPLET_IFACE,
334 flashlight_applet_dbus_request_handler, plugin) != OSSO_OK) {
335 g_critical ("flashlight_status_plugin_init: Unable to register D-BUS request handler\n");
339 /* initialize dbus */
340 dbus_error_init (&error);
341 priv->dbus_connection = dbus_bus_get (DBUS_BUS_SYSTEM, &error);
342 if (dbus_error_is_set (&error)) {
343 g_critical ("flashlight_status_plugin_init: Could not get the system DBus connection, %s",
345 dbus_error_free (&error);
349 /* initialize flashlight */
350 if (flashlight_init (&priv->flashlight) < 0) {
351 g_critical ("flashlight_status_plugin_init: Unable to create Flashlight context\n");
356 priv->hal = libhal_ctx_new ();
358 g_critical ("flashlight_status_plugin_init: Unable to create HAL context\n");
362 libhal_ctx_set_dbus_connection (priv->hal, priv->dbus_connection);
363 libhal_ctx_set_user_data (priv->hal, plugin);
364 libhal_ctx_set_device_property_modified (priv->hal,
365 flashlight_status_plugin_on_hal_property_modified);
367 if (!libhal_ctx_init (priv->hal, &error)) {
368 if (dbus_error_is_set (&error)) {
369 g_critical ("Could not initialize the HAL context, %s",
371 dbus_error_free (&error);
373 g_critical ("Could not initialize the HAL context, "
374 "no error, is hald running?");
376 libhal_ctx_set_user_data (priv->hal, NULL);
377 libhal_ctx_free (priv->hal);
382 libhal_device_add_property_watch (priv->hal, CAM_COVER_UDI, NULL);
384 /* create plugin ui */
385 priv->button = flashlight_status_plugin_ui (plugin);
386 gtk_container_add (GTK_CONTAINER (plugin), priv->button);
388 /* show widget if camera cover is open */
389 if ( !libhal_device_get_property_bool (priv->hal, CAM_COVER_UDI, CAM_COVER_STATE, NULL))
390 gtk_widget_show_all (GTK_WIDGET (plugin));
395 flashlight_status_plugin_finalize (GObject *object)
397 FlashlightPlugin *plugin = FLASHLIGHT_STATUS_PLUGIN (object);
398 FlashlightPluginPrivate *priv = FLASHLIGHT_STATUS_PLUGIN_GET_PRIVATE (plugin);
400 g_return_if_fail (priv);
402 /* deinitialize hal */
404 libhal_device_remove_property_watch (priv->hal, CAM_COVER_UDI, NULL);
405 libhal_ctx_set_user_data (priv->hal, NULL);
406 libhal_ctx_shutdown (priv->hal, NULL);
407 libhal_ctx_free (priv->hal);
411 /* unreference dbus connection */
412 if (priv->dbus_connection) {
413 dbus_connection_unref (priv->dbus_connection);
415 priv->dbus_connection = NULL;
417 /* cancel status timer */
418 if (priv->status_timer) {
419 g_source_remove (priv->status_timer);
421 priv->status_timer = 0;
423 /* deinitialize flashlight */
424 if (priv->flashlight) {
425 flashlight_deinit (priv->flashlight);
427 priv->flashlight = NULL;
429 /* deinitialize osso */
430 if (priv->osso_context) {
431 osso_deinitialize (priv->osso_context);
433 priv->osso_context = NULL;
435 G_OBJECT_CLASS (flashlight_status_plugin_parent_class)->finalize (object);