viewer/evntlst.cpp

Go to the documentation of this file.
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 //#include                                      "pipes.h"
00027 #include          "fileerr.h"
00028 //#include                                      "sbderrs.h"
00029 //#include                                      "grpherr.h"
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                                  //anything new in queue
00040 EXTERN BOOL8 event_waiting = FALSE;
00041 
00042 #ifdef __UNIX__
00043                                  //semaphore count
00044 static INT32 event_critical_section = 0;
00045                                  //true if pending
00046 static BOOL8 event_pending = FALSE;
00047 EXTERN BOOL8 handler_set;        //true if signal handler on
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(                        //signal handler
00061                    int,                    //signal
00062                    int,                    //code
00063                    struct sigcontext *scp  //info for sigvector
00064                   ) {
00065   //scp->sc_syscall_action=SIG_RESTART;        //restart sys calls
00066   event_pending = TRUE;
00067   if (!event_critical_section) {
00068     lock_events(); 
00069     unlock_events(); 
00070   }
00071 }
00072 
00073 
00079 BOOL8 check_event(            /*test for event */
00080                   INT16 fd,   /*window to wait on */
00081                   BOOL8 wait  /*set if waiting */
00082                  ) {
00083   GRAPHICS_EVENT event;          /*event from daemon */
00084   SBD_GRAPHICS_EVENT sbd_event;  //event from pipe
00085   BOOL8 gotone;                  /*repeat while do */
00086   INT32 time;                    /*time to select */
00087   INT32 typein;                  //input type
00088   INT32 keyin;                   //input key
00089   INT32 fdin;                    //input fd
00090   int scanresult;                //of fscanf
00091   static FILE *eventsin = NULL;  //input file
00092 
00093                                  // && sbfds[fd].used!=1)
00094   if (fd < 0 || fd > maxsbfd || fd > 0) {
00095     //   BADSBFD.error("check_event",LOG,NULL);     /*report error*/
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                                  //remove name
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         //    fprintf(stderr,"Read input on %d\n", fdin );
00125         event.type = (INT8) typein;
00126         event.key = (char) keyin;
00127         event.fildes = fdin;
00128         add_event(&event);  //got one
00129         gotone = gotone || fd == 0 || fd == event.fildes;
00130         /*know if we got one */
00131       }
00132     }
00133   }
00134   while (!gotone) {  
00135 //   && select_read(shminfo.fds[INFD],time)!=0) /*event available*/
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);  /*add event to queue */
00147                                  /*know if we got one */
00148       gotone = gotone || fd == 0 || fd == event.fildes;
00149     }
00150     else
00151       kick_daemon(COUNT_READS);  /*keep count accurate */
00152     time = CHECK_TIME;
00153   }
00154   return gotone;
00155 }
00156 
00157 
00158 #else // of ifdef __UNIX__
00159 EXTERN HANDLE event_sem = NULL;  //event lock
00160 
00168 void event_reader(             /*read events */
00169                   void *param  /*file descriptor */
00170                  ) {
00171   #ifndef __MAC__
00172                                  //real file descriptor
00173   HANDLE *fdptr = (HANDLE *) param;
00174   HANDLE fd = *fdptr;            //real file descriptor
00175   unsigned long nread;           //bytes read
00176   SBD_GRAPHICS_EVENT event;      /*event from daemon */
00177   GRAPHICS_EVENT real_event;     //converted format
00178   char pipe_char[2];             //from pipe
00179   INT32 pipe_index;              //index to event queue
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);  /*add event to queue */
00197     }
00198     else
00199       kick_daemon(COUNT_READS);  /*got acknowledge */
00200   }
00201   CloseHandle(fd); 
00202   *fdptr = NULL;
00203   _endthread(); 
00204   #endif
00205 }
00206 #endif // of ifdef __UNIX__
00207 
00211 void add_event(                       /*add an event */
00212                GRAPHICS_EVENT *event  /*event to add */
00213               ) {
00214   GRAPHICS_EVENT *newevent;      /*new event */
00215   EVENT_HANDLER handler;         //avoid race hazards
00216   GRAPHICS_EVENT sel_event;      //selection
00217                                  //last button down
00218   static GRAPHICS_EVENT last_down;
00219 
00220   #ifdef __UNIX__
00221   static FILE *eventsout = NULL; //output file
00222   static STRING outname;         //output name
00223 
00224                                  //doing anything
00225   if (events_logfile.string ()[0] != '\0' || eventsout != NULL) {
00226     if (eventsout != NULL        //already open
00227     && outname != (STRING &) events_logfile) {
00228       fclose(eventsout);  //finished that one
00229       eventsout = NULL;
00230     }
00231                                  //needs opening
00232     if (eventsout == NULL && events_logfile.string ()[0] != '\0') {
00233                                  //save name
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   //      fprintf(stderr,"Received event of type %d at (%f,%f) on %d\n",
00244   //              event->type,event->x,event->y,event->fildes);
00245   event->fd = &sbfds[event->fildes];
00246   switch (event->type) {
00247     case DOWN_EVENT:
00248       last_down = *event;        //save it
00249       handler = sbfds[event->fildes].click_handler;
00250       if (handler != NULL) {
00251         (*handler) (event);
00252         return;                  //done it
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;                  //done it
00273       }
00274       break;
00275     case KEYPRESS_EVENT:
00276       handler = sbfds[event->fildes].key_handler;
00277       if (handler != NULL) {
00278         (*handler) (event);
00279         return;                  //done it
00280       }
00281       break;
00282     case DESTROY_EVENT:
00283       handler = sbfds[event->fildes].destroy_handler;
00284       if (handler != NULL) {
00285         (*handler) (event);
00286         //                      return;                                                                         //done it
00287       }
00288       break;
00289   }
00290   lock_events(); 
00291   newevent = new GRAPHICS_EVENT;
00292   if (newevent != NULL) {
00293     *newevent = *event;          /*copy event */
00294                                  /*first event */
00295     if (sbfds[event->fildes].events == NULL)
00296       sbfds[event->fildes].events = newevent;
00297     else
00298                                  /*add to end */
00299       sbfds[event->fildes].lastevent->next = newevent;
00300                                  /*is new end */
00301     sbfds[event->fildes].lastevent = newevent;
00302     newevent->next = NULL;
00303   }
00304   event_waiting = TRUE;          //added to queue
00305   unlock_events(); 
00306 }
00307 
00308 
00312 void lock_events() {  //lock
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() {  //lock
00325   #ifdef __UNIX__
00326   if (event_pending && event_critical_section == 1) {
00327                                  //get all events
00328     while (check_event (0, FALSE));
00329     event_pending = FALSE;
00330   }
00331   event_critical_section--;
00332   #elif defined (__MSW32__)
00333                                  //release it
00334   ReleaseSemaphore (event_sem, 1, NULL);
00335   #endif
00336 }

Generated on Wed Feb 28 19:49:12 2007 for Tesseract by  doxygen 1.5.1