view mcabber/src/events.c @ 830:80434fde7cfa

Display presence notification timestamps when they exist These timestamps were used in the roster, but not in the buffer window message nor in the history logfile. Reported by "ze".
author Mikael Berthe <mikael@lilotux.net>
date Wed, 03 May 2006 11:28:41 +0200
parents 80bd7f49075f
children 2de8f8ba1f34
line wrap: on
line source

/*
 * events.c     -- Events fonctions
 *
 * Copyright (C) 2006 Mikael Berthe <bmikael@lists.lilotux.net>
 *
 * 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 <glib.h>
#include "events.h"
#include "logprint.h"

static GSList *evs_list; // Events list

static eviqs *evs_find(const char *evid);

//  evs_new(type, timeout)
// Create an events structure.
eviqs *evs_new(guint8 type, time_t timeout)
{
  static guint evs_idn;
  eviqs *new_evs;
  time_t now_t;
  char *stridn;

  if (!++evs_idn)
    evs_idn = 1;
  /* Check for wrapping, we shouldn't reuse ids */
  stridn = g_strdup_printf("%d", evs_idn);
  if (evs_find(stridn))  {
    g_free(stridn);
    // We could try another id but for now giving up should be fine...
    return NULL;
  }

  new_evs = g_new0(eviqs, 1);
  time(&now_t);
  new_evs->ts_create = now_t;
  if (timeout)
    new_evs->ts_expire = now_t + timeout;
  new_evs->type = type;
  new_evs->id = stridn;

  evs_list = g_slist_append(evs_list, new_evs);
  return new_evs;
}

int evs_del(const char *evid)
{
  GSList *p;
  eviqs *i;

  if (!evid) return 1;

  for (p = evs_list; p; p = g_slist_next(p)) {
    i = p->data;
    if (!strcmp(evid, i->id))
      break;
  }
  if (p) {
    g_free(i->id);
    if (i->xmldata) xmlnode_free(i->xmldata);
    g_free(i->data);
    g_free(i->desc);
    g_free(i);
    evs_list = g_slist_remove(evs_list, p->data);
    return 0; // Ok, deleted
  }
  return -1;  // Not found
}

static eviqs *evs_find(const char *evid)
{
  GSList *p;
  eviqs *i;

  if (!evid) return NULL;

  for (p = evs_list; p; p = g_slist_next(p)) {
    i = p->data;
    if (!strcmp(evid, i->id))
      return i;
  }
  return NULL;
}

//  evs_callback(evid, evcontext)
// Callback processing for the specified event.
// Return 0 in case of success, -1 if the evid hasn't been found.
int evs_callback(const char *evid, guint evcontext)
{
  eviqs *i;

  i = evs_find(evid);
  if (!i) return -1;

  // IQ processing
  // Note: If xml_result is NULL, this is a timeout
  if (i->callback)
    (*i->callback)(i, evcontext);

  evs_del(evid);
  return 0;
}

void evs_check_timeout(time_t now_t)
{
  GSList *p;
  eviqs *i;

  p = evs_list;
  while (p) {
    i = p->data;
    // We must get next IQ eviqs element now because the current one
    // could be freed.
    p = g_slist_next(p);

    if ((!i->ts_expire && now_t > i->ts_create + EVS_MAX_TIMEOUT) ||
        (i->ts_expire && now_t > i->ts_expire)) {
      evs_callback(i->id, EVS_CONTEXT_TIMEOUT);
    }
  }
}

void evs_display_list(void)
{
  GSList *p;
  eviqs *i;

  scr_LogPrint(LPRINT_LOGNORM, "Events list:");
  for (p = evs_list; p; p = g_slist_next(p)) {
    i = p->data;
    scr_LogPrint(LPRINT_LOGNORM,
                 "Id: %-3s %s", i->id, (i->desc ? i->desc : ""));
  }
  scr_LogPrint(LPRINT_LOGNORM, "End of events list.");
}

//  evs_geteventslist(bool comp)
// Return a singly-linked-list of events ids, for the completion system.
// If comp is true, the string "list" is added (it's a completion argument).
// Note: the caller should free the list (and data) after use.
GSList *evs_geteventslist(int compl)
{
  GSList *evidlist = NULL, *p;
  eviqs *i;

  for (p = evs_list; p; p = g_slist_next(p)) {
    i = p->data;
    evidlist = g_slist_append(evidlist, g_strdup(i->id));
  }

  if (compl) {
    // Last item is the "list" subcommand.
    evidlist = g_slist_append(evidlist, g_strdup("list"));
  }
  return evidlist;
}

/* vim: set expandtab cindent cinoptions=>2\:2(0:  For Vim users... */