2007-12-30 16:41:49 +00:00
|
|
|
/***************************************************************************
|
|
|
|
|
|
|
|
watcher.cpp
|
|
|
|
|
|
|
|
(c) 2004-2006 - Daniel Campos Fernández <dcamposf@gmail.com>
|
2009-08-17 10:41:51 +00:00
|
|
|
|
2007-12-30 16:41:49 +00:00
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU General Public License as published by
|
2009-08-17 10:41:51 +00:00
|
|
|
the Free Software Foundation; either version 2, or (at your option)
|
2007-12-30 16:41:49 +00:00
|
|
|
any later version.
|
|
|
|
|
|
|
|
This program 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 this program; if not, write to the Free Software
|
2011-06-03 00:51:09 +00:00
|
|
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
2011-12-31 02:39:20 +00:00
|
|
|
MA 02110-1301, USA.
|
2007-12-30 16:41:49 +00:00
|
|
|
|
|
|
|
***************************************************************************/
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <gtk/gtk.h>
|
|
|
|
#include "main.h"
|
|
|
|
#include "gambas.h"
|
|
|
|
#include "watcher.h"
|
|
|
|
|
2009-06-07 00:01:59 +00:00
|
|
|
static WATCH **watch = NULL;
|
2007-12-30 16:41:49 +00:00
|
|
|
|
2009-06-06 23:31:48 +00:00
|
|
|
static gboolean watch_adaptor(GIOChannel *source, GIOCondition condition, gpointer param)
|
2007-12-30 16:41:49 +00:00
|
|
|
{
|
2009-06-06 23:31:48 +00:00
|
|
|
WATCH *data = (WATCH *)param;
|
2007-12-30 16:41:49 +00:00
|
|
|
|
|
|
|
if (!data) return true;
|
|
|
|
|
|
|
|
switch (condition)
|
|
|
|
{
|
|
|
|
case G_IO_IN:
|
2009-06-07 00:01:59 +00:00
|
|
|
(*data->callback_read)(data->fd, GB_WATCH_READ, data->param_read); break;
|
2007-12-30 16:41:49 +00:00
|
|
|
case G_IO_OUT:
|
2009-06-07 00:01:59 +00:00
|
|
|
(*data->callback_write)(data->fd, GB_WATCH_WRITE, data->param_write); break;
|
2007-12-30 16:41:49 +00:00
|
|
|
default: break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2009-06-06 23:31:48 +00:00
|
|
|
void CWatcher::init()
|
2007-12-30 16:41:49 +00:00
|
|
|
{
|
2009-06-07 00:01:59 +00:00
|
|
|
GB.NewArray(POINTER(&watch), sizeof(WATCH *), 0);
|
2009-06-06 23:31:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void CWatcher::exit()
|
|
|
|
{
|
2009-06-07 00:01:59 +00:00
|
|
|
Clear();
|
2009-06-06 23:31:48 +00:00
|
|
|
GB.FreeArray(POINTER(&watch));
|
|
|
|
}
|
2007-12-30 16:41:49 +00:00
|
|
|
|
2009-06-06 23:31:48 +00:00
|
|
|
void CWatcher::Clear()
|
|
|
|
{
|
|
|
|
while (count())
|
2007-12-30 16:41:49 +00:00
|
|
|
{
|
2009-06-07 00:01:59 +00:00
|
|
|
CWatcher::Add(watch[0]->fd, GB_WATCH_NONE, NULL, 0);
|
2007-12-30 16:41:49 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void CWatcher::Remove(int fd)
|
|
|
|
{
|
|
|
|
CWatcher::Add(fd,GB_WATCH_NONE,NULL,0);
|
|
|
|
}
|
|
|
|
|
2009-06-06 23:31:48 +00:00
|
|
|
void CWatcher::Add(int fd, int type, void *callback, intptr_t param)
|
2007-12-30 16:41:49 +00:00
|
|
|
{
|
2009-06-06 23:31:48 +00:00
|
|
|
WATCH *data = NULL;
|
2009-06-07 00:01:59 +00:00
|
|
|
WATCH **pwatch;
|
2009-06-06 23:31:48 +00:00
|
|
|
int i;
|
2007-12-30 16:41:49 +00:00
|
|
|
|
2009-06-06 23:31:48 +00:00
|
|
|
for (i = 0; i < count(); i++)
|
2007-12-30 16:41:49 +00:00
|
|
|
{
|
2009-06-07 00:01:59 +00:00
|
|
|
if (watch[i]->fd == fd)
|
|
|
|
{
|
|
|
|
data = watch[i];
|
2009-06-06 23:31:48 +00:00
|
|
|
break;
|
2009-06-07 00:01:59 +00:00
|
|
|
}
|
2007-12-30 16:41:49 +00:00
|
|
|
}
|
|
|
|
|
2009-06-06 23:31:48 +00:00
|
|
|
if (!data)
|
2007-12-30 16:41:49 +00:00
|
|
|
{
|
2009-06-06 23:31:48 +00:00
|
|
|
if (type == GB_WATCH_NONE || !callback)
|
|
|
|
return;
|
|
|
|
|
2009-06-07 00:01:59 +00:00
|
|
|
pwatch = (WATCH **)GB.Add(&watch);
|
|
|
|
GB.Alloc(POINTER(pwatch), sizeof(WATCH));
|
|
|
|
data = *pwatch;
|
2009-06-06 23:31:48 +00:00
|
|
|
data->fd = fd;
|
2009-06-07 00:01:59 +00:00
|
|
|
data->channel_read = data->channel_write = 0;
|
2009-06-06 23:31:48 +00:00
|
|
|
data->callback_read = data->callback_write = 0;
|
2007-12-30 16:41:49 +00:00
|
|
|
}
|
2009-06-06 23:31:48 +00:00
|
|
|
|
|
|
|
if (data->callback_read && (type == GB_WATCH_NONE || type == GB_WATCH_READ))
|
2007-12-30 16:41:49 +00:00
|
|
|
{
|
2009-06-06 23:31:48 +00:00
|
|
|
g_source_remove(data->id_read);
|
2009-06-07 00:01:59 +00:00
|
|
|
g_io_channel_unref(data->channel_read);
|
2009-06-06 23:31:48 +00:00
|
|
|
data->callback_read = 0;
|
2009-06-07 00:01:59 +00:00
|
|
|
data->channel_read = 0;
|
2009-06-06 23:31:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (data->callback_write && (type == GB_WATCH_NONE || type == GB_WATCH_WRITE))
|
|
|
|
{
|
|
|
|
g_source_remove(data->id_write);
|
2009-06-07 00:01:59 +00:00
|
|
|
g_io_channel_unref(data->channel_write);
|
2009-06-06 23:31:48 +00:00
|
|
|
data->callback_write = 0;
|
2009-06-07 00:01:59 +00:00
|
|
|
data->channel_write = 0;
|
2009-06-06 23:31:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (callback)
|
|
|
|
{
|
|
|
|
if (type == GB_WATCH_READ)
|
2007-12-30 16:41:49 +00:00
|
|
|
{
|
2009-06-06 23:31:48 +00:00
|
|
|
data->callback_read = (WATCH_CALLBACK)callback;
|
2009-06-07 00:01:59 +00:00
|
|
|
data->param_read = param;
|
|
|
|
data->channel_read = g_io_channel_unix_new(fd);
|
|
|
|
g_io_channel_set_encoding(data->channel_read, NULL, NULL);
|
|
|
|
data->id_read = g_io_add_watch_full(data->channel_read, G_PRIORITY_LOW, G_IO_IN, watch_adaptor, (void*)data, NULL);
|
2009-06-06 23:31:48 +00:00
|
|
|
}
|
2009-06-07 00:01:59 +00:00
|
|
|
else if (type == GB_WATCH_WRITE)
|
2009-06-06 23:31:48 +00:00
|
|
|
{
|
|
|
|
data->callback_write = (WATCH_CALLBACK)callback;
|
2009-06-07 00:01:59 +00:00
|
|
|
data->param_write = param;
|
|
|
|
data->channel_write = g_io_channel_unix_new(fd);
|
|
|
|
g_io_channel_set_encoding(data->channel_write, NULL, NULL);
|
|
|
|
data->id_write = g_io_add_watch_full(data->channel_write, G_PRIORITY_LOW, G_IO_OUT, watch_adaptor, (void*)data, NULL);
|
2007-12-30 16:41:49 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-06-06 23:31:48 +00:00
|
|
|
if (!data->callback_read && !data->callback_write)
|
2007-12-30 16:41:49 +00:00
|
|
|
{
|
2009-06-07 00:01:59 +00:00
|
|
|
GB.Free(POINTER(&data));
|
2009-06-06 23:31:48 +00:00
|
|
|
GB.Remove(&watch, i, 1);
|
2007-12-30 16:41:49 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int CWatcher::count()
|
|
|
|
{
|
2009-06-06 23:31:48 +00:00
|
|
|
return GB.Count(watch);
|
2007-12-30 16:41:49 +00:00
|
|
|
}
|