00001 #include <stdlib.h>
00002 #include <stdio.h>
00003 #include <errno.h>
00004 #include <sys/fcntl.h>
00005 #include <poll.h>
00006 #include <unistd.h>
00007 #include <sstream>
00008
00009 #include "FCam/Event.h"
00010 #include "FCam/Time.h"
00011
00012 #include "ButtonListener.h"
00013 #include "../Debug.h"
00014
00015
00016
00017
00018 namespace FCam {
00019 namespace N900 {
00020
00021 void *button_listener_thread_(void *arg) {
00022 ButtonListener *b = (ButtonListener *)arg;
00023 b->run();
00024 pthread_exit(NULL);
00025 return NULL;
00026 }
00027
00028 ButtonListener *ButtonListener::instance() {
00029 if (!_instance) {
00030 _instance = new ButtonListener;
00031 }
00032 return _instance;
00033 }
00034
00035 ButtonListener::ButtonListener() : stop(false) {
00036 pthread_attr_t attr;
00037 struct sched_param param;
00038
00039
00040
00041 param.sched_priority = sched_get_priority_max(SCHED_OTHER);
00042
00043 pthread_attr_init(&attr);
00044
00045 if ((errno =
00046 -(pthread_attr_setschedparam(&attr, ¶m) ||
00047 pthread_attr_setschedpolicy(&attr, SCHED_OTHER) ||
00048 pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED) ||
00049 pthread_create(&thread, &attr, button_listener_thread_, this)))) {
00050 error(Event::InternalError, "Error creating button listener thread");
00051 }
00052
00053 }
00054
00055 ButtonListener::~ButtonListener() {
00056 stop = true;
00057 pthread_join(thread, NULL);
00058 }
00059
00060 void ButtonListener::run() {
00061
00062
00063
00064
00065
00066 if (!fork()) {
00067 dprintf(2, "Killing camera-ui using dsmetool\n");
00068
00069 close(STDOUT_FILENO);
00070 close(STDERR_FILENO);
00071 execl("/usr/sbin/dsmetool",
00072 "/usr/sbin/dsmetool",
00073 "-k", "/usr/bin/camera-ui",
00074 (char *)NULL);
00075 exit(0);
00076 }
00077
00078 if (!fork()) {
00079
00080 usleep(100000);
00081 dprintf(2, "Killing camera-ui using killall\n");
00082
00083 close(STDOUT_FILENO);
00084 close(STDERR_FILENO);
00085 execl("/usr/bin/killall", "/usr/bin/killall", "camera-ui", (char *)NULL);
00086 exit(0);
00087 }
00088
00089 const int BUTTONS = 4;
00090
00091 const char *fnames[BUTTONS] = {"/sys/devices/platform/gpio-switch/cam_shutter/state",
00092 "/sys/devices/platform/gpio-switch/cam_focus/state",
00093 "/sys/devices/platform/gpio-switch/cam_launch/state",
00094 "/sys/devices/platform/gpio-switch/slide/state"};
00095
00096 char buf[81];
00097
00098 bool state[BUTTONS];
00099
00100 int event[BUTTONS*2] = {Event::N900LensOpened,
00101 Event::N900LensClosed,
00102 Event::FocusPressed,
00103 Event::FocusReleased,
00104 Event::ShutterPressed,
00105 Event::ShutterReleased,
00106 Event::N900SlideOpened,
00107 Event::N900SlideClosed};
00108
00109 std::string descriptions[BUTTONS*2] = {"Lens cover opened",
00110 "Lens cover closed",
00111 "Focus button pressed",
00112 "Focus button released",
00113 "Shutter button pressed",
00114 "Shutter button released",
00115 "Keyboard slide opened",
00116 "Keyboard slide closed"};
00117
00118
00119 int rval;
00120 struct pollfd fds[BUTTONS];
00121 for (int i = 0; i < BUTTONS; i++) {
00122 fds[i].fd = open(fnames[i], O_RDONLY);
00123 fds[i].events = POLLPRI;
00124 fds[i].revents = 0;
00125 }
00126
00127
00128 for (int i = 0; i < BUTTONS; i++) {
00129 rval = read(fds[i].fd, &buf, 80);
00130 buf[rval] = 0;
00131 switch (buf[0]) {
00132 case 'c':
00133 case 'i':
00134 state[i] = false;
00135 break;
00136 case 'o':
00137 case 'a':
00138 state[i] = true;
00139 break;
00140 default:
00141 error(Event::InternalError, "ButtonListener: Unknown state: %s", buf);
00142 }
00143 }
00144
00145 while (!stop) {
00146
00147 rval = poll(fds, BUTTONS, 1000);
00148 if (rval == -1) {
00149
00150 dprintf(2, "ButtonListener: poll failed");
00151
00152 continue;
00153 }
00154 if (rval == 0) continue;
00155
00156 for (int i = 0; i < BUTTONS; i++) {
00157 if (fds[i].revents & POLLPRI) {
00158 close(fds[i].fd);
00159 fds[i].fd = open(fnames[i], O_RDONLY, 0);
00160 rval = read(fds[i].fd, &buf, 80);
00161 buf[rval] = 0;
00162 switch (buf[0]) {
00163 case 'c':
00164 case 'i':
00165 if (state[i] != false) {
00166 state[i] = false;
00167 postEvent(event[i*2+1], 0, descriptions[i*2+1]);
00168 }
00169 break;
00170 case 'o':
00171 case 'a':
00172 if (state[i] != true) {
00173 state[i] = true;
00174 postEvent(event[i*2], 0, descriptions[i*2]);
00175 }
00176 break;
00177 default:
00178 error(Event::InternalError, "ButtonListener: Unknown state: %s", buf);
00179 }
00180 }
00181 }
00182 }
00183
00184 dprintf(2, "Button listener shutting down\n");
00185
00186 for (int i = 0; i < BUTTONS; i++) {
00187 close(fds[i].fd);
00188 }
00189
00190
00191 if (!fork()) {
00192
00193 execl("/usr/sbin/dsmetool",
00194 "/usr/sbin/dsmetool",
00195 "-U", "user",
00196 "-o", "/usr/bin/camera-ui",
00197 (char *)NULL);
00198
00199 error(Event::InternalError, "Error restarting camera-ui");
00200 exit(0);
00201 }
00202 }
00203
00204 ButtonListener *ButtonListener::_instance = NULL;
00205 }
00206 }
00207
00208