summaryrefslogtreecommitdiff
path: root/hald-addon-generic-light-sensor.c
diff options
context:
space:
mode:
authorHenrik Rydberg <rydberg@euromail.se>2008-11-13 03:05:38 +0100
committerHenrik Rydberg <rydberg@euromail.se>2008-11-13 03:05:38 +0100
commit49680952052582ff3dd11bc413b6287b65063b2a (patch)
treea1c1f2dce3ad12f6464088f235d631e94b9af616 /hald-addon-generic-light-sensor.c
Initial GIT version: hal-applesmc-0.14
Signed-off-by: Henrik Rydberg <rydberg@euromail.se>
Diffstat (limited to 'hald-addon-generic-light-sensor.c')
-rw-r--r--hald-addon-generic-light-sensor.c212
1 files changed, 212 insertions, 0 deletions
diff --git a/hald-addon-generic-light-sensor.c b/hald-addon-generic-light-sensor.c
new file mode 100644
index 0000000..e724290
--- /dev/null
+++ b/hald-addon-generic-light-sensor.c
@@ -0,0 +1,212 @@
1/***************************************************************************
2 *
3 * addon-generic-light.c:
4 * Copyright (C) 2008 Henrik Rydberg <rydberg@euromail.se>
5 *
6 * Based on addon-generic-backlight.c:
7 * Copyright (C) 2008 Danny Kukawka <danny.kukawka@web.de>
8 *
9 * Licensed under the Academic Free License version 2.1
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 *
25 **************************************************************************/
26
27#include <string.h>
28#include <sys/types.h>
29#include <sys/stat.h>
30#include <fcntl.h>
31#include <unistd.h>
32#include <stdio.h>
33#include <stdlib.h>
34
35#include "glib-abi.h"
36#include "dbus-abi.h"
37#include "hal-abi.h"
38
39#define HAL_PROPERTY "org.freedesktop.Hal.Device.LightSensor"
40#define MAX_SENSORS 16
41
42static const char prop_name[] = HAL_PROPERTY;
43static const char prop_invalid[] = HAL_PROPERTY ".Invalid";
44static const char prop_get[] = "GetBrightness";
45
46static struct GMainLoop *main_loop;
47static struct LibHalContext *halctx;
48static struct DBusConnection *conn;
49
50static char sysfs_path[512];
51static int sensors, levels;
52
53/**
54 * Get keyboard backlight level
55 *
56 * Tries to read from the specified sysfs device, and if successful,
57 * updates the internal keyboard backlight state. Warns if the device
58 * cannot be opened or be read from. Always returns the last succesful
59 * read.
60 */
61static void get_light_sensor(int *level, int nlevel)
62{
63 static const char delim[] = " ,()";
64 static int sensor[MAX_SENSORS];
65 int fd, i;
66 char buf[64], *p;
67
68 fd = open(sysfs_path, O_RDONLY);
69 if (fd < 0) {
70 HAL_WARNING(("Could not open '%s'", sysfs_path));
71 goto err;
72 }
73
74 memset(buf, 0, sizeof(buf));
75 if (read(fd, buf, sizeof(buf)) < 0) {
76 HAL_WARNING(("Could not read from '%s'", sysfs_path));
77 goto close;
78 }
79
80 p = strtok(buf, delim);
81 for (i = 0; p && i < nlevel; i++) {
82 sensor[i] = atoi(p);
83 p = strtok(NULL, delim);
84 HAL_DEBUG(("light_sensor[%d]=%d", i, sensor[i]));
85 }
86
87close:
88 close(fd);
89err:
90 for (i = 0; i < nlevel; i++)
91 level[i] = sensor[i] < levels ? sensor[i]: levels - 1;
92}
93
94/* DBus set keyboard backlight level */
95static struct DBusMessage *dbus_get_light_sensor(struct DBusMessage *msg)
96{
97 struct DBusError err;
98 struct DBusMessage *reply;
99 int level[MAX_SENSORS];
100
101 dbus_error_init(&err);
102 if (!dbus_message_get_args(msg, &err, DBUS_TYPE_INVALID))
103 return dbus_message_new_error(msg, prop_invalid,
104 "Invalid message");
105
106 get_light_sensor(level, sensors);
107
108 reply = dbus_message_new_method_return(msg);
109 if (reply) {
110 int *pb = level;
111 dbus_message_append_args(reply, DBUS_TYPE_ARRAY,
112 DBUS_TYPE_INT32, &pb, sensors, DBUS_TYPE_INVALID);
113 }
114
115 return reply;
116}
117
118/* DBus filter function */
119static DBusHandlerResult filter_function(struct DBusConnection *connection,
120 struct DBusMessage *message,
121 void *userdata)
122{
123 struct DBusMessage *reply = NULL;
124
125 if (dbus_message_is_method_call(message, prop_name, prop_get))
126 reply = dbus_get_light_sensor(message);
127
128 if (reply) {
129 dbus_connection_send(connection, reply, NULL);
130 dbus_message_unref(reply);
131 }
132
133 return DBUS_HANDLER_RESULT_HANDLED;
134}
135
136int main(int argc, char *argv[])
137{
138 struct DBusError err;
139 struct stat fs;
140
141 char *udi = getenv("UDI");
142 char *path = getenv("HAL_PROP_LINUX_SYSFS_PATH");
143 char *sensor_str = getenv("HAL_PROP_LIGHT_SENSOR_NUM_SENSORS");
144 char *level_str = getenv("HAL_PROP_LIGHT_SENSOR_NUM_LEVELS");
145
146 setup_logger();
147
148 if (udi == NULL) {
149 HAL_ERROR(("No device specified"));
150 return -2;
151 }
152 if (path == NULL) {
153 HAL_ERROR(("No sysfs path specified"));
154 return -2;
155 }
156 if (sensor_str == NULL) {
157 HAL_ERROR(("No light_sensor.num_sensors defined"));
158 return -2;
159 }
160 if (level_str == NULL) {
161 HAL_ERROR(("No light_sensor.num_levels defined"));
162 return -2;
163 }
164
165 sensors = atoi(sensor_str);
166 levels = atoi(level_str);
167 snprintf(sysfs_path, sizeof(sysfs_path), "%s", path);
168
169 HAL_DEBUG(("udi='%s', path='%s', sensors='%d', levels='%d'",
170 udi, path, sensors, levels));
171
172 if (sensors >= MAX_SENSORS) {
173 HAL_ERROR(("light_sensor.num_sensors is too large"));
174 return -2;
175 }
176 if (stat(sysfs_path, &fs)) {
177 HAL_ERROR(("The sysfs property path does not exist"));
178 return -2;
179 }
180
181 dbus_error_init(&err);
182 halctx = libhal_ctx_init_direct(&err);
183
184 if (halctx == NULL) {
185 HAL_ERROR(("Cannot connect to hald"));
186 return -3;
187 }
188
189 conn = libhal_ctx_get_dbus_connection(halctx);
190 dbus_connection_setup_with_g_main(conn, NULL);
191
192 dbus_connection_add_filter(conn, filter_function, NULL, NULL);
193
194 if (!libhal_device_claim_interface(halctx, udi, prop_name,
195 " <method name=\"GetBrightness\">\n"
196 " <arg name=\"brightness_value\" direction=\"out\" type=\"i\"/>\n"
197 " </method>\n",
198 &err)) {
199 HAL_ERROR(("Cannot claim interface '" HAL_PROPERTY "'"));
200 return -4;
201 }
202
203 dbus_error_init(&err);
204 if (!libhal_device_addon_is_ready(halctx, udi, &err))
205 return -4;
206
207 main_loop = g_main_loop_new(NULL, FALSE);
208 g_main_loop_run(main_loop);
209
210 return 0;
211}
212