diff --git a/configure.ac b/configure.ac index 984a493..c892469 100644 --- a/configure.ac +++ b/configure.ac @@ -18,7 +18,6 @@ VIRT_VIEWER_COMPILE_WARNINGS(maximum) PKG_CHECK_MODULES(LIBXML2, libxml-2.0 >= 2.6.0) PKG_CHECK_MODULES(LIBVIRT, libvirt >= 0.5.0) -PKG_CHECK_MODULES(LIBVIRT_GLIB, libvirt-glib >= 0.0.1) PKG_CHECK_MODULES(GTK2, gtk+-2.0 >= 2.10.0) PKG_CHECK_MODULES(LIBGLADE2, libglade-2.0 >= 2.6.0) PKG_CHECK_MODULES(GTKVNC, gtk-vnc-1.0 >= 0.3.5) diff --git a/mingw32-virt-viewer.spec.in b/mingw32-virt-viewer.spec.in index 2491149..0092dc4 100644 --- a/mingw32-virt-viewer.spec.in +++ b/mingw32-virt-viewer.spec.in @@ -17,7 +17,6 @@ BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) BuildRequires: mingw32-filesystem >= 23 BuildRequires: mingw32-gtk2 -BuildRequires: mingw32-libvirt-glib BuildRequires: mingw32-libvirt >= 0.5.0 BuildRequires: mingw32-libxml2 BuildRequires: mingw32-libglade2 diff --git a/plugin/Makefile.am b/plugin/Makefile.am index 71aa467..242d442 100644 --- a/plugin/Makefile.am +++ b/plugin/Makefile.am @@ -13,8 +13,7 @@ virt_viewer_plugin_la_LIBADD = \ @GTK2_LIBS@ \ @LIBXML2_LIBS@ \ @LIBGLADE2_LIBS@ \ - @LIBVIRT_LIBS@ \ - @LIBVIRT_GLIB_LIBS@ + @LIBVIRT_LIBS@ virt_viewer_plugin_la_LDFLAGS = \ -module -avoid-version virt_viewer_plugin_la_CFLAGS = \ @@ -25,7 +24,6 @@ virt_viewer_plugin_la_CFLAGS = \ @LIBXML2_CFLAGS@ \ @LIBGLADE2_CFLAGS@ \ @LIBVIRT_CFLAGS@ \ - @LIBVIRT_GLIB_CFLAGS@ \ -DGLADE_DIR="\"$(pkgdatadir)/ui\"" \ @WARN_CFLAGS@ \ -I$(top_srcdir)/src diff --git a/src/Makefile.am b/src/Makefile.am index ef0b767..cd2f0ec 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -8,6 +8,7 @@ EXTRA_DIST = $(glade_DATA) virt_viewer_SOURCES = \ main.c \ + events.h events.c \ viewer.h viewer.c virt_viewer_LDADD = \ @@ -15,8 +16,7 @@ virt_viewer_LDADD = \ @GTK2_LIBS@ \ @LIBXML2_LIBS@ \ @LIBGLADE2_LIBS@ \ - @LIBVIRT_LIBS@ \ - @LIBVIRT_GLIB_LIBS@ + @LIBVIRT_LIBS@ virt_viewer_CFLAGS = \ @GTKVNC_CFLAGS@ \ @@ -24,6 +24,5 @@ virt_viewer_CFLAGS = \ @LIBXML2_CFLAGS@ \ @LIBGLADE2_CFLAGS@ \ @LIBVIRT_CFLAGS@ \ - @LIBVIRT_GLIB_CFLAGS@ \ @WARN_CFLAGS@ \ -DGLADE_DIR="\"$(gladedir)\"" diff --git a/src/events.c b/src/events.c new file mode 100644 index 0000000..92e4a76 --- /dev/null +++ b/src/events.c @@ -0,0 +1,321 @@ +/* + * events.c: event loop integration + * + * Copyright (C) 2008-2009 Daniel P. Berrange + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Daniel P. Berrange + */ + + +#include +#include +#include +#include +#include + +#include "events.h" + +static gboolean debugFlag = FALSE; + +#define DEBUG(fmt, ...) do { if (G_UNLIKELY(debugFlag)) g_debug(fmt, ## __VA_ARGS__); } while (0) + +struct viewer_event_handle +{ + int watch; + int fd; + int events; + int enabled; + GIOChannel *channel; + guint source; + virEventHandleCallback cb; + void *opaque; + virFreeCallback ff; +}; + +static int nextwatch = 1; +static unsigned int nhandles = 0; +static struct viewer_event_handle **handles = NULL; + +static gboolean +viewer_event_dispatch_handle(GIOChannel *source G_GNUC_UNUSED, + GIOCondition condition, + gpointer opaque) +{ + struct viewer_event_handle *data = opaque; + int events = 0; + + if (condition & G_IO_IN) + events |= VIR_EVENT_HANDLE_READABLE; + if (condition & G_IO_OUT) + events |= VIR_EVENT_HANDLE_WRITABLE; + if (condition & G_IO_HUP) + events |= VIR_EVENT_HANDLE_HANGUP; + if (condition & G_IO_ERR) + events |= VIR_EVENT_HANDLE_ERROR; + + DEBUG("Dispatch handler %d %d %p\n", data->fd, events, data->opaque); + + (data->cb)(data->watch, data->fd, events, data->opaque); + + return TRUE; +} + + +static +int viewer_event_add_handle(int fd, + int events, + virEventHandleCallback cb, + void *opaque, + virFreeCallback ff) +{ + struct viewer_event_handle *data; + GIOCondition cond = 0; + + handles = g_realloc(handles, sizeof(*handles)*(nhandles+1)); + data = g_malloc(sizeof(*data)); + memset(data, 0, sizeof(*data)); + + if (events & VIR_EVENT_HANDLE_READABLE) + cond |= G_IO_IN; + if (events & VIR_EVENT_HANDLE_WRITABLE) + cond |= G_IO_OUT; + + data->watch = nextwatch++; + data->fd = fd; + data->events = events; + data->cb = cb; + data->opaque = opaque; + data->channel = g_io_channel_unix_new(fd); + data->ff = ff; + + DEBUG("Add handle %d %d %p\n", data->fd, events, data->opaque); + + data->source = g_io_add_watch(data->channel, + cond, + viewer_event_dispatch_handle, + data); + + handles[nhandles++] = data; + + return data->watch; +} + +static struct viewer_event_handle * +viewer_event_find_handle(int watch) +{ + unsigned int i; + for (i = 0 ; i < nhandles ; i++) + if (handles[i]->watch == watch) + return handles[i]; + + return NULL; +} + +static void +viewer_event_update_handle(int watch, + int events) +{ + struct viewer_event_handle *data = viewer_event_find_handle(watch); + + if (!data) { + DEBUG("Update for missing handle watch %d", watch); + return; + } + + if (events) { + GIOCondition cond = 0; + if (events == data->events) + return; + + if (data->source) + g_source_remove(data->source); + + cond |= G_IO_HUP; + if (events & VIR_EVENT_HANDLE_READABLE) + cond |= G_IO_IN; + if (events & VIR_EVENT_HANDLE_WRITABLE) + cond |= G_IO_OUT; + data->source = g_io_add_watch(data->channel, + cond, + viewer_event_dispatch_handle, + data); + data->events = events; + } else { + if (!data->source) + return; + + g_source_remove(data->source); + data->source = 0; + data->events = 0; + } +} + +static int +viewer_event_remove_handle(int watch) +{ + struct viewer_event_handle *data = viewer_event_find_handle(watch); + + if (!data) { + DEBUG("Remove of missing watch %d", watch); + return -1; + } + + DEBUG("Remove handle %d %d\n", watch, data->fd); + + g_source_remove(data->source); + data->source = 0; + data->events = 0; + if (data->ff) + (data->ff)(data->opaque); + free(data); + + return 0; +} + +struct viewer_event_timeout +{ + int timer; + int interval; + guint source; + virEventTimeoutCallback cb; + void *opaque; + virFreeCallback ff; +}; + + +static int nexttimer = 1; +static unsigned int ntimeouts = 0; +static struct viewer_event_timeout **timeouts = NULL; + +static gboolean +viewer_event_dispatch_timeout(void *opaque) +{ + struct viewer_event_timeout *data = opaque; + DEBUG("Dispatch timeout %p %p %d %p\n", data, data->cb, data->timer, data->opaque); + (data->cb)(data->timer, data->opaque); + + return TRUE; +} + +static int +viewer_event_add_timeout(int interval, + virEventTimeoutCallback cb, + void *opaque, + virFreeCallback ff) +{ + struct viewer_event_timeout *data; + + timeouts = g_realloc(timeouts, sizeof(*timeouts)*(ntimeouts+1)); + data = g_malloc(sizeof(*data)); + memset(data, 0, sizeof(*data)); + + data->timer = nexttimer++; + data->interval = interval; + data->cb = cb; + data->opaque = opaque; + data->ff = ff; + if (interval >= 0) + data->source = g_timeout_add(interval, + viewer_event_dispatch_timeout, + data); + + timeouts[ntimeouts++] = data; + + DEBUG("Add timeout %p %d %p %p %d\n", data, interval, cb, opaque, data->timer); + + return data->timer; +} + + +static struct viewer_event_timeout * +viewer_event_find_timeout(int timer) +{ + unsigned int i; + for (i = 0 ; i < ntimeouts ; i++) + if (timeouts[i]->timer == timer) + return timeouts[i]; + + return NULL; +} + + +static void +viewer_event_update_timeout(int timer, + int interval) +{ + struct viewer_event_timeout *data = viewer_event_find_timeout(timer); + + if (!data) { + DEBUG("Update of missing timer %d", timer); + return; + } + + DEBUG("Update timeout %p %d %d\n", data, timer, interval); + + if (interval >= 0) { + if (data->source) + return; + + data->interval = interval; + data->source = g_timeout_add(data->interval, + viewer_event_dispatch_timeout, + data); + } else { + if (!data->source) + return; + + g_source_remove(data->source); + data->source = 0; + } +} + +static int +viewer_event_remove_timeout(int timer) +{ + struct viewer_event_timeout *data = viewer_event_find_timeout(timer); + + if (!data) { + DEBUG("Remove of missing timer %d", timer); + return -1; + } + + DEBUG("Remove timeout %p %d\n", data, timer); + + if (!data->source) + return -1; + + g_source_remove(data->source); + data->source = 0; + + if (data->ff) + (data->ff)(data->opaque); + + free(data); + + return 0; +} + + +void viewer_event_register(void) { + virEventRegisterImpl(viewer_event_add_handle, + viewer_event_update_handle, + viewer_event_remove_handle, + viewer_event_add_timeout, + viewer_event_update_timeout, + viewer_event_remove_timeout); +} + diff --git a/src/events.h b/src/events.h new file mode 100644 index 0000000..974bc34 --- /dev/null +++ b/src/events.h @@ -0,0 +1,30 @@ +/* + * events.h: event loop integration + * + * Copyright (C) 2008-2009 Daniel P. Berrange + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Daniel P. Berrange + */ + + + +#ifndef VIRT_VIEWER_EVENT_H +#define VIRT_VIEWER_EVENT_H + +void viewer_event_register(void); + +#endif diff --git a/src/viewer.c b/src/viewer.c index 09f5500..4039e84 100644 --- a/src/viewer.c +++ b/src/viewer.c @@ -33,7 +33,6 @@ #include #include #include -#include #include #include @@ -50,6 +49,7 @@ #endif #include "viewer.h" +#include "events.h" static gboolean doDebug = FALSE; #define DEBUG_LOG(s, ...) do { if (doDebug) g_debug((s), ## __VA_ARGS__); } while (0) @@ -1105,7 +1105,7 @@ viewer_start (const char *uri, g_value_init(&viewer->accelSetting, G_TYPE_STRING); - virEventRegisterGLib(); + viewer_event_register(); virSetErrorFunc(NULL, viewer_error_func); viewer->conn = virConnectOpenReadOnly(uri); diff --git a/virt-viewer.spec.in b/virt-viewer.spec.in index 868372b..89a22f8 100644 --- a/virt-viewer.spec.in +++ b/virt-viewer.spec.in @@ -58,7 +58,6 @@ browsers. %configure %endif %__make %{?_smp_mflags} -%__make %{?_smp_mflags} %install