00001
00020 #include "mfcpch.h"
00021 #include "grphshm.h"
00022 #include "grphics.h"
00023 #ifdef __UNIX__
00024 #include <unistd.h>
00025 #include <signal.h>
00026
00027 #include "fileerr.h"
00028
00029
00030 #elif defined (__MSW32__)
00031 #include <io.h>
00032 #include <process.h>
00033 #else
00034 #include <unistd.h>
00035 #endif
00036 #include "evntlst.h"
00037
00038 #define EXTERN
00039
00040 EXTERN BOOL8 event_waiting = FALSE;
00041
00042 #ifdef __UNIX__
00043
00044 static INT32 event_critical_section = 0;
00045
00046 static BOOL8 event_pending = FALSE;
00047 EXTERN BOOL8 handler_set;
00048
00051 EXTERN STRING_VAR (events_logfile, "", "File to log events to");
00052 EXTERN STRING_VAR (events_playback, "", "File to read events from");
00060 void event_handler(
00061 int,
00062 int,
00063 struct sigcontext *scp
00064 ) {
00065
00066 event_pending = TRUE;
00067 if (!event_critical_section) {
00068 lock_events();
00069 unlock_events();
00070 }
00071 }
00072
00073
00079 BOOL8 check_event(
00080 INT16 fd,
00081 BOOL8 wait
00082 ) {
00083 GRAPHICS_EVENT event;
00084 SBD_GRAPHICS_EVENT sbd_event;
00085 BOOL8 gotone;
00086 INT32 time;
00087 INT32 typein;
00088 INT32 keyin;
00089 INT32 fdin;
00090 int scanresult;
00091 static FILE *eventsin = NULL;
00092
00093
00094 if (fd < 0 || fd > maxsbfd || fd > 0) {
00095
00096 return FALSE;
00097 }
00098 time = wait ? AWAIT_TIME : CHECK_TIME;
00099 gotone = FALSE;
00100 while (!gotone
00101 && (events_playback.string ()[0] != '\0' || eventsin != NULL)) {
00102 if (eventsin == NULL && events_playback.string ()[0] != '\0') {
00103 if ((eventsin = fopen (events_playback.string (), "r")) == NULL)
00104 CANTOPENFILE.error ("check_event", LOG,
00105 events_playback.string ());
00106
00107 events_playback.set_value (NULL);
00108 }
00109 if (eventsin != NULL) {
00110 scanresult =
00111 fscanf (eventsin,
00112 INT32FORMAT " " INT32FORMAT "(%f,%f) on " INT32FORMAT,
00113 &typein, &keyin, &event.x, &event.y, &fdin);
00114 if (scanresult != 5) {
00115 if (scanresult == EOF)
00116 fprintf (stderr, "Closing input event file\n");
00117 else
00118 fprintf (stderr, "Error on event input: copied %d values\n",
00119 scanresult);
00120 fclose(eventsin);
00121 eventsin = NULL;
00122 }
00123 else {
00124
00125 event.type = (INT8) typein;
00126 event.key = (char) keyin;
00127 event.fildes = fdin;
00128 add_event(&event);
00129 gotone = gotone || fd == 0 || fd == event.fildes;
00130
00131 }
00132 }
00133 }
00134 while (!gotone) {
00135
00136 if (read (shminfo.fds[INFD], &sbd_event, sizeof (SBD_GRAPHICS_EVENT))
00137 != sizeof (SBD_GRAPHICS_EVENT))
00138 READFAILED.error ("check_event", EXIT, "sbdaemon pipe");
00139 if (sbd_event.type != QUEUE_CLEAR) {
00140 event.fildes = sbd_event.fd;
00141 event.type = sbd_event.type;
00142 event.key = sbd_event.key;
00143 event.x = sbd_event.x;
00144 event.y = sbd_event.y;
00145 event.next = NULL;
00146 add_event(&event);
00147
00148 gotone = gotone || fd == 0 || fd == event.fildes;
00149 }
00150 else
00151 kick_daemon(COUNT_READS);
00152 time = CHECK_TIME;
00153 }
00154 return gotone;
00155 }
00156
00157
00158 #else // of ifdef __UNIX__
00159 EXTERN HANDLE event_sem = NULL;
00160
00168 void event_reader(
00169 void *param
00170 ) {
00171 #ifndef __MAC__
00172
00173 HANDLE *fdptr = (HANDLE *) param;
00174 HANDLE fd = *fdptr;
00175 unsigned long nread;
00176 SBD_GRAPHICS_EVENT event;
00177 GRAPHICS_EVENT real_event;
00178 char pipe_char[2];
00179 INT32 pipe_index;
00180
00181 event_id = GetCurrentThreadId ();
00182 while (ReadFile (fd, pipe_char, 2, &nread, NULL) != 0 && nread == 2) {
00183 pipe_index = EVENT_HEAD;
00184 event = EVENT_INDEX (pipe_index);
00185 pipe_index++;
00186 if (pipe_index >= EVENTSIZE)
00187 pipe_index = 0;
00188 EVENT_HEAD = pipe_index;
00189 if (event.type != QUEUE_CLEAR) {
00190 real_event.fildes = event.fd;
00191 real_event.type = event.type;
00192 real_event.key = event.key;
00193 real_event.x = event.x;
00194 real_event.y = event.y;
00195 real_event.next = NULL;
00196 add_event(&real_event);
00197 }
00198 else
00199 kick_daemon(COUNT_READS);
00200 }
00201 CloseHandle(fd);
00202 *fdptr = NULL;
00203 _endthread();
00204 #endif
00205 }
00206 #endif // of ifdef __UNIX__
00207
00211 void add_event(
00212 GRAPHICS_EVENT *event
00213 ) {
00214 GRAPHICS_EVENT *newevent;
00215 EVENT_HANDLER handler;
00216 GRAPHICS_EVENT sel_event;
00217
00218 static GRAPHICS_EVENT last_down;
00219
00220 #ifdef __UNIX__
00221 static FILE *eventsout = NULL;
00222 static STRING outname;
00223
00224
00225 if (events_logfile.string ()[0] != '\0' || eventsout != NULL) {
00226 if (eventsout != NULL
00227 && outname != (STRING &) events_logfile) {
00228 fclose(eventsout);
00229 eventsout = NULL;
00230 }
00231
00232 if (eventsout == NULL && events_logfile.string ()[0] != '\0') {
00233
00234 outname = events_logfile.string ();
00235 if ((eventsout = fopen (outname.string (), "w")) == NULL)
00236 CANTOPENFILE.error ("add_event", LOG, outname.string ());
00237 }
00238 if (eventsout != NULL)
00239 fprintf (eventsout, "%d %d(%f,%f) on %d\n",
00240 event->type, event->key, event->x, event->y, event->fildes);
00241 }
00242 #endif
00243
00244
00245 event->fd = &sbfds[event->fildes];
00246 switch (event->type) {
00247 case DOWN_EVENT:
00248 last_down = *event;
00249 handler = sbfds[event->fildes].click_handler;
00250 if (handler != NULL) {
00251 (*handler) (event);
00252 return;
00253 }
00254 break;
00255 case UP_EVENT:
00256 sel_event = *event;
00257 if (last_down.x > event->x)
00258 sel_event.xmax = last_down.x;
00259 else {
00260 sel_event.xmax = event->x;
00261 sel_event.x = last_down.x;
00262 }
00263 if (last_down.y > event->y)
00264 sel_event.ymax = last_down.y;
00265 else {
00266 sel_event.ymax = event->y;
00267 sel_event.y = last_down.y;
00268 }
00269 handler = sbfds[event->fildes].selection_handler;
00270 if (handler != NULL) {
00271 (*handler) (&sel_event);
00272 return;
00273 }
00274 break;
00275 case KEYPRESS_EVENT:
00276 handler = sbfds[event->fildes].key_handler;
00277 if (handler != NULL) {
00278 (*handler) (event);
00279 return;
00280 }
00281 break;
00282 case DESTROY_EVENT:
00283 handler = sbfds[event->fildes].destroy_handler;
00284 if (handler != NULL) {
00285 (*handler) (event);
00286
00287 }
00288 break;
00289 }
00290 lock_events();
00291 newevent = new GRAPHICS_EVENT;
00292 if (newevent != NULL) {
00293 *newevent = *event;
00294
00295 if (sbfds[event->fildes].events == NULL)
00296 sbfds[event->fildes].events = newevent;
00297 else
00298
00299 sbfds[event->fildes].lastevent->next = newevent;
00300
00301 sbfds[event->fildes].lastevent = newevent;
00302 newevent->next = NULL;
00303 }
00304 event_waiting = TRUE;
00305 unlock_events();
00306 }
00307
00308
00312 void lock_events() {
00313 #ifdef __UNIX__
00314 event_critical_section++;
00315 #elif defined (__MSW32__)
00316 WaitForSingleObject (event_sem, (unsigned long) -1);
00317 #endif
00318 }
00319
00320
00324 void unlock_events() {
00325 #ifdef __UNIX__
00326 if (event_pending && event_critical_section == 1) {
00327
00328 while (check_event (0, FALSE));
00329 event_pending = FALSE;
00330 }
00331 event_critical_section--;
00332 #elif defined (__MSW32__)
00333
00334 ReleaseSemaphore (event_sem, 1, NULL);
00335 #endif
00336 }