/* giFTui * Copyright (C) 2003 the giFTui team * * 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 the Free Software Foundation; either version 2 of the * License, or (at your option) 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 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA. */ #include "main.h" #include #include #include #include #include #include #include #include "event.h" #include "io.h" #include "util.h" typedef struct _GiftIO_t { GIOChannel *io; GSource *source; } GiftIO_t; static GiftIO_t gift_io = {NULL, NULL}; /**/ guint gift_id_new (void) { static guint id = 1; if (!id) id++; return id++; } /**/ void gift_send_local_str (gchar *str) { Interface *in; g_return_if_fail (str != NULL); #if HAVE_DEBUG GIFTUI_PRINT_INFO (("<-: %s\n", str)); #endif if ((in = interface_unserialize (str, strlen (str)))) { GiftuiEvent_t *ev; ev = giftui_event_new_from_interface (in); giftui_event_send_to_widgets (ev); giftui_event_free (ev); } else GIFTUI_PRINT_ERR (("libgift failed to unsearialize data.\n")); return; } /* Put a NULL arg at the end. */ void gift_send_local (gchar *key, gchar *sub, ...) { gchar *value; va_list list; String *buf; Interface *iface; iface = interface_new (key, sub); va_start (list, sub); while ((key = va_arg (list, gchar *)) != NULL) { value = va_arg (list, gchar *); interface_put (iface, key, value); } va_end (list); buf = interface_serialize (iface); interface_free (iface); gift_send_local_str (buf->str); string_free (buf); return; } /**/ void gift_send_str (const gchar *str) { g_return_if_fail (gift_io.io != NULL); g_return_if_fail (str != NULL); #ifdef HAVE_DEBUG GIFTUI_PRINT_INFO (("->: %s\n", str)); #endif g_io_channel_write_chars (gift_io.io, str, strlen (str), NULL, NULL); g_io_channel_flush (gift_io.io, NULL); return; } void gift_send_interface (Interface *out) { String *buf; g_return_if_fail (gift_io.io != NULL); g_return_if_fail (out != NULL); buf = interface_serialize (out); gift_send_str (buf->str); string_free (buf); return; } void gift_send (gchar *key, gchar *sub, ...) { Interface *iface; String *buf; va_list list; gchar *value; g_return_if_fail (gift_io.io != NULL); g_return_if_fail (key != NULL); iface = interface_new (key, sub); va_start (list, sub); while ((key = va_arg (list, gchar *)) != NULL) { value = va_arg (list, gchar *); interface_put (iface, key, value); } va_end (list); buf = interface_serialize (iface); interface_free (iface); gift_send_str (buf->str); string_free (buf); return; } /**/ static void gift_close (void) { guint tag; /* Close & unref io */ g_io_channel_shutdown (gift_io.io, TRUE, NULL); g_io_channel_unref (gift_io.io); /* Stop & unref timeout */ tag = g_source_get_id (gift_io.source); g_source_remove (tag); g_source_unref (gift_io.source); /* yo ! */ gift_io.io = NULL; gift_io.source = NULL; return; } gboolean gift_receive (void) { gchar *str = NULL; GIOStatus s; static GIOStatus status_last = G_IO_STATUS_NORMAL; g_return_val_if_fail (gift_io.io != NULL, FALSE); s = g_io_channel_read_line (gift_io.io, &str, NULL, NULL, NULL); switch (s) { case G_IO_STATUS_NORMAL: if (str != NULL) { gift_send_local_str (str); g_free (str); } break; case G_IO_STATUS_ERROR: if (status_last != G_IO_STATUS_ERROR) gift_send_local_str ("MESSAGE(Error when reading giFT message);\n"); break; case G_IO_STATUS_EOF: default: gift_send_local_str ("DISCONNECT(Connection with giFT broken);\n"); gift_close (); return FALSE; } status_last = s; return TRUE; } gboolean gift_connect (const gchar *server, gint port) { int sock; struct hostent *host; gchar line[] = {';', '\n'}; g_return_val_if_fail (server != NULL, FALSE); g_return_val_if_fail (port > 0, FALSE); if ((sock = socket (AF_INET, SOCK_STREAM, 0)) != -1) { struct sockaddr_in addr; host = gethostbyname (server); if (!host) return FALSE; addr.sin_addr = * (struct in_addr *) host->h_addr; addr.sin_port = g_htons(port); addr.sin_family = AF_INET; if (connect (sock, (struct sockaddr *) &addr, sizeof (addr)) == -1) return FALSE; } else return FALSE; gift_io.io = g_io_channel_unix_new (sock); g_io_channel_set_buffer_size (gift_io.io, 0); g_io_channel_set_line_term (gift_io.io, line, 2); g_io_channel_set_encoding (gift_io.io, "ISO-8859-1", NULL); gift_io.source = g_io_create_watch (gift_io.io, G_IO_IN | G_IO_PRI); g_source_set_priority (gift_io.source, G_PRIORITY_LOW); g_source_set_callback (gift_io.source, (GSourceFunc) gift_receive, NULL, NULL); g_source_attach (gift_io.source, NULL); return TRUE; } void gift_disconnect (void) { g_return_if_fail (gift_io.io != NULL); gift_send_str ("DETACH;"); gift_send_local_str ("CLOSE(Connection with giFT closed);"); gift_close (); return; } void gift_quit (void) { g_return_if_fail (gift_io.io != NULL); gift_send_str ("QUIT;"); gift_send_local_str ("CLOSE(Connection with giFT closed);"); gift_close (); return; } /**/ gboolean gift_connected (void) { if (gift_io.io != NULL) return TRUE; return FALSE; }