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 >
Wrap
C/C++ Source or Header
|
1994-04-19
|
6KB
|
246 lines
/* x11_eventloop.c -- Eventloop for X11
Copyright (C) 1993, 1994 John Harper <jsh@ukc.ac.uk>
This file is part of Jade.
Jade is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
Jade is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Jade; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "jade.h"
#include "jade_protos.h"
#ifdef HAVE_UNIX
# include <sys/types.h>
# include <sys/time.h>
# include <errno.h>
#else
you lose
#endif
_PR VALUE eventloop(void);
static VALUE
handleevent(XEvent *xev)
{
VW *oldvw = CurrVW, *ev_vw;
VALUE result = sym_nil;
/* stdtitle(CurrVW); */
ev_vw = findwindowvw(xev->xany.window);
if(ev_vw)
{
switch(xev->type)
{
Event ev;
case MappingNotify:
XRefreshKeyboardMapping(&xev->xmapping);
break;
case Expose:
handleexpose(ev_vw, &xev->xexpose);
if(ev_vw == oldvw)
cursor(ev_vw, CURS_ON);
break;
case ConfigureNotify:
if((ev_vw->vw_WindowSys.ws_Width != xev->xconfigure.width)
|| (ev_vw->vw_WindowSys.ws_Height != xev->xconfigure.height))
{
if(ev_vw == oldvw)
cursor(ev_vw, CURS_OFF);
if((ev_vw->vw_WindowSys.ws_Height != 0)
&& (ev_vw->vw_WindowSys.ws_Height < xev->xconfigure.height))
{
/* Have to clear out the status line. It can be left in
the wrong place. */
CLR_AREA(ev_vw, 0, ev_vw->vw_WindowSys.ws_MessageLineY,
ev_vw->vw_WindowSys.ws_Width, ev_vw->vw_FontY+2);
}
ev_vw->vw_WindowSys.ws_Width = xev->xconfigure.width;
ev_vw->vw_WindowSys.ws_Height = xev->xconfigure.height;
_updatedimensions(ev_vw, xev->xconfigure.width, xev->xconfigure.height);
if(ev_vw == oldvw)
cursor(ev_vw, CURS_ON);
}
break;
case ClientMessage:
if((xev->xclient.format == 32)
&& (xev->xclient.data.l[0] == Wm_Del_Win))
{
CurrVW = ev_vw;
if(ev_vw != oldvw)
cursor(oldvw, CURS_OFF);
else
cursor(ev_vw, CURS_OFF);
result = cmd_eval_hook2(MKSTR("close-gadget-hook"), sym_nil);
if(CurrVW)
{
refreshworld();
cursor(CurrVW, CURS_ON);
}
}
break;
case FocusIn:
if(ev_vw != oldvw)
{
cursor(oldvw, CURS_OFF);
cursor(ev_vw, CURS_ON);
CurrVW = ev_vw;
}
break;
case ButtonPress:
case ButtonRelease:
case KeyPress:
ev.ev_EventDef.evd_Type = ev.ev_EventDef.evd_Mods = ev.ev_EventDef.evd_Code = 0;
translateevent(&ev, xev);
if(ev.ev_EventDef.evd_Type)
{
CurrVW = ev_vw;
if(oldvw != ev_vw)
cursor(oldvw, CURS_OFF);
ev.ev_Window = ev_vw;
result = usekey(xev, &ev, (ev_vw == oldvw));
}
break;
}
}
return(result);
}
VALUE
eventloop(void)
{
VALUE result = sym_nil;
RecurseDepth++;
refreshworldcurs();
while(CurrVW)
{
#ifdef HAVE_UNIX
fd_set copy;
struct timeval timeout;
int number, i;
#endif
/*
* HERE... Read out all events in Q
*/
while(XEventsQueued(XDisplay, QueuedAfterReading) > 0)
{
XEvent ev;
XNextEvent(XDisplay, &ev);
if(!(result = handleevent(&ev)))
{
if(ThrowValue)
{
VALUE car = VCAR(ThrowValue);
if(car == sym_exit)
{
result = VCDR(ThrowValue);
ThrowValue = NULL;
if(RecurseDepth > 0)
goto end;
}
else if((car == sym_top_level) && (RecurseDepth == 0))
{
result = VCDR(ThrowValue);
ThrowValue = NULL;
}
else if(car == sym_quit)
goto end;
else if(car == sym_error)
{
handleerror(VCAR(VCDR(ThrowValue)), VCDR(VCDR(ThrowValue)));
ThrowValue = NULL;
result = sym_nil;
}
else if(RecurseDepth == 0)
{
ThrowValue = NULL;
result = sym_nil;
#if 0
/* This is no good -- we have to do the error NOW */
cmd_signal(sym_no_catcher, LIST_1(car));
#else
handleerror(sym_no_catcher, LIST_1(car));
#endif
}
else
goto end;
}
else
{
result = sym_nil;
ThrowValue = NULL;
}
}
if(!CurrVW)
goto end;
stdtitle(CurrVW);
if(CurrVW->vw_Flags & VWFF_REFRESH_STATUS)
{
setvwtitle(CurrVW);
CurrVW->vw_Flags &= ~VWFF_REFRESH_STATUS;
}
}
XFlush(XDisplay);
#ifdef HAVE_UNIX
copy = FdReadSet;
timeout.tv_sec = EVENT_TIMEOUT_LENGTH;
timeout.tv_usec = 0;
number = select(FD_SETSIZE, ©, NULL, NULL, &timeout);
if(number > 0)
{
/*
* no need to test first 3 descriptors
*/
i = 3;
while(number > 0)
{
if(FD_ISSET(i, ©))
{
number--;
if(FdReadAction[i])
FdReadAction[i](i);
}
i++;
}
}
else if(number == 0)
{
/*
* auto-save's are only done after the select() timeout.
* This is for two reasons:
* 1. save wasting lots of cpu-time
* 2. minimises inconvenience of waiting for buffer(s) to be
* saved while typing (ie, it should rarely happen).
*
* I'm not sure how long to make the timeout??
*/
if(!autosavebuffers())
{
/* nothing was saved so try a GC */
if(DataAfterGC > IdleDataBeforeGC)
cmd_garbage_collect(sym_t);
}
}
#else
whatever you like...
#endif /* HAVE_UNIX */
/*
* This is only needed in case some process wrote to a buffer
*/
refreshworldcurs();
}
end:
RecurseDepth--;
return(result);
}