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