home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 4 / FreshFish_May-June1994.bin / bbs / may94 / util / edit / jade.lha / Jade / src / x11_eventloop.c < prev    next >
C/C++ Source or Header  |  1994-04-19  |  6KB  |  246 lines

  1. /* x11_eventloop.c -- Eventloop for X11
  2.    Copyright (C) 1993, 1994 John Harper <jsh@ukc.ac.uk>
  3.  
  4. This file is part of Jade.
  5.  
  6. Jade is free software; you can redistribute it and/or modify it
  7. under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 2, or (at your option)
  9. any later version.
  10.  
  11. Jade is distributed in the hope that it will be useful, but
  12. WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. GNU General Public License for more details.
  15.  
  16. You should have received a copy of the GNU General Public License
  17. along with Jade; see the file COPYING.  If not, write to
  18. the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  19.  
  20. #include "jade.h"
  21. #include "jade_protos.h"
  22.  
  23. #ifdef HAVE_UNIX
  24. # include <sys/types.h>
  25. # include <sys/time.h>
  26. # include <errno.h>
  27. #else
  28.   you lose
  29. #endif
  30.  
  31. _PR VALUE eventloop(void);
  32.  
  33. static VALUE
  34. handleevent(XEvent *xev)
  35. {
  36.     VW *oldvw = CurrVW, *ev_vw;
  37.     VALUE result = sym_nil;
  38. /*  stdtitle(CurrVW); */
  39.     ev_vw = findwindowvw(xev->xany.window);
  40.     if(ev_vw)
  41.     {
  42.     switch(xev->type)
  43.     {
  44.         Event ev;
  45.     case MappingNotify:
  46.         XRefreshKeyboardMapping(&xev->xmapping);
  47.         break;
  48.     case Expose:
  49.         handleexpose(ev_vw, &xev->xexpose);
  50.         if(ev_vw == oldvw)
  51.         cursor(ev_vw, CURS_ON);
  52.         break;
  53.     case ConfigureNotify:
  54.         if((ev_vw->vw_WindowSys.ws_Width != xev->xconfigure.width)
  55.            || (ev_vw->vw_WindowSys.ws_Height != xev->xconfigure.height))
  56.         {
  57.         if(ev_vw == oldvw)
  58.             cursor(ev_vw, CURS_OFF);
  59.         if((ev_vw->vw_WindowSys.ws_Height != 0)
  60.            && (ev_vw->vw_WindowSys.ws_Height < xev->xconfigure.height))
  61.         {
  62.             /* Have to clear out the status line. It can be left in
  63.                the wrong place.     */
  64.             CLR_AREA(ev_vw, 0, ev_vw->vw_WindowSys.ws_MessageLineY,
  65.                  ev_vw->vw_WindowSys.ws_Width, ev_vw->vw_FontY+2);
  66.         }
  67.         ev_vw->vw_WindowSys.ws_Width = xev->xconfigure.width;
  68.         ev_vw->vw_WindowSys.ws_Height = xev->xconfigure.height;
  69.         _updatedimensions(ev_vw, xev->xconfigure.width, xev->xconfigure.height);
  70.         if(ev_vw == oldvw)
  71.             cursor(ev_vw, CURS_ON);
  72.         }
  73.         break;
  74.     case ClientMessage:
  75.         if((xev->xclient.format == 32)
  76.         && (xev->xclient.data.l[0] == Wm_Del_Win))
  77.         {
  78.         CurrVW = ev_vw;
  79.         if(ev_vw != oldvw)
  80.             cursor(oldvw, CURS_OFF);
  81.         else
  82.             cursor(ev_vw, CURS_OFF);
  83.         result = cmd_eval_hook2(MKSTR("close-gadget-hook"), sym_nil);
  84.         if(CurrVW)
  85.         {
  86.             refreshworld();
  87.             cursor(CurrVW, CURS_ON);
  88.         }
  89.         }
  90.         break;
  91.     case FocusIn:
  92.         if(ev_vw != oldvw)
  93.         {
  94.         cursor(oldvw, CURS_OFF);
  95.         cursor(ev_vw, CURS_ON);
  96.         CurrVW = ev_vw;
  97.         }
  98.         break;
  99.     case ButtonPress:
  100.     case ButtonRelease:
  101.     case KeyPress:
  102.         ev.ev_EventDef.evd_Type = ev.ev_EventDef.evd_Mods = ev.ev_EventDef.evd_Code = 0;
  103.         translateevent(&ev, xev);
  104.         if(ev.ev_EventDef.evd_Type)
  105.         {
  106.         CurrVW = ev_vw;
  107.         if(oldvw != ev_vw)
  108.             cursor(oldvw, CURS_OFF);
  109.         ev.ev_Window = ev_vw;
  110.         result = usekey(xev, &ev, (ev_vw == oldvw));
  111.         }
  112.         break;
  113.     }
  114.     }
  115.     return(result);
  116. }
  117.  
  118. VALUE
  119. eventloop(void)
  120. {
  121.     VALUE result = sym_nil;
  122.     RecurseDepth++;
  123.     refreshworldcurs();
  124.     while(CurrVW)
  125.     {
  126. #ifdef HAVE_UNIX
  127.     fd_set copy;
  128.     struct timeval timeout;
  129.     int number, i;
  130. #endif
  131.     /*
  132.      * HERE... Read out all events in Q
  133.      */
  134.     while(XEventsQueued(XDisplay, QueuedAfterReading) > 0)
  135.     {
  136.         XEvent ev;
  137.         XNextEvent(XDisplay, &ev);
  138.         if(!(result = handleevent(&ev)))
  139.         {
  140.         if(ThrowValue)
  141.         {
  142.             VALUE car = VCAR(ThrowValue);
  143.             if(car == sym_exit)
  144.             {
  145.             result = VCDR(ThrowValue);
  146.             ThrowValue = NULL;
  147.             if(RecurseDepth > 0)
  148.                 goto end;
  149.             }
  150.             else if((car == sym_top_level) && (RecurseDepth == 0))
  151.             {
  152.             result = VCDR(ThrowValue);
  153.             ThrowValue = NULL;
  154.             }
  155.             else if(car == sym_quit)
  156.             goto end;
  157.             else if(car == sym_error)
  158.             {
  159.             handleerror(VCAR(VCDR(ThrowValue)), VCDR(VCDR(ThrowValue)));
  160.             ThrowValue = NULL;
  161.             result = sym_nil;
  162.             }
  163.             else if(RecurseDepth == 0)
  164.             {
  165.             ThrowValue = NULL;
  166.             result = sym_nil;
  167. #if 0
  168.             /* This is no good -- we have to do the error NOW */
  169.             cmd_signal(sym_no_catcher, LIST_1(car));
  170. #else
  171.             handleerror(sym_no_catcher, LIST_1(car));
  172. #endif
  173.             }
  174.             else
  175.             goto end;
  176.         }
  177.         else
  178.         {
  179.             result = sym_nil;
  180.             ThrowValue = NULL;
  181.         }
  182.         }
  183.         if(!CurrVW)
  184.         goto end;
  185.         stdtitle(CurrVW);
  186.         if(CurrVW->vw_Flags & VWFF_REFRESH_STATUS)
  187.         {
  188.         setvwtitle(CurrVW);
  189.         CurrVW->vw_Flags &= ~VWFF_REFRESH_STATUS;
  190.         }
  191.     }
  192.     XFlush(XDisplay);
  193.  
  194. #ifdef HAVE_UNIX
  195.     copy = FdReadSet;
  196.     timeout.tv_sec = EVENT_TIMEOUT_LENGTH;
  197.     timeout.tv_usec = 0;
  198.     number = select(FD_SETSIZE, ©, NULL, NULL, &timeout);
  199.     if(number > 0)
  200.     {
  201.         /*
  202.          * no need to test first 3 descriptors
  203.          */
  204.         i = 3;
  205.         while(number > 0)
  206.         {
  207.         if(FD_ISSET(i, ©))
  208.         {
  209.             number--;
  210.             if(FdReadAction[i])
  211.             FdReadAction[i](i);
  212.         }
  213.         i++;
  214.         }
  215.     }
  216.     else if(number == 0)
  217.     {
  218.         /*
  219.          * auto-save's are only done after the select() timeout.
  220.          * This is for two reasons:
  221.          *    1. save wasting lots of cpu-time
  222.          *    2. minimises inconvenience of waiting for buffer(s) to be
  223.          *    saved while typing (ie, it should rarely happen).
  224.          *
  225.          * I'm not sure how long to make the timeout??
  226.          */
  227.         if(!autosavebuffers())
  228.         {
  229.         /* nothing was saved so try a GC */
  230.         if(DataAfterGC > IdleDataBeforeGC)
  231.             cmd_garbage_collect(sym_t);
  232.         }
  233.     }
  234. #else
  235.     whatever you like...
  236. #endif /* HAVE_UNIX */
  237.     /*
  238.      * This is only needed in case some process wrote to a buffer
  239.      */
  240.     refreshworldcurs();
  241.     }
  242. end:
  243.     RecurseDepth--;
  244.     return(result);
  245. }
  246.