Logo Search packages:      
Sourcecode: beryl-core version File versions

ipcs.c

/**
 *
 * Beryl Inter-Plugin-Communication-System
 *
 * Copyright : (C) 2006 by Dennis Kasprzyk
 * E-mail    : onestone@beryl-project.org
 *
 * Lightly modified by : (C) 2006 Quinn Storm
 * E-mail              : quinnstorm@beryl-project.org
 *
 *
 * 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.
 *
 **/

#include <beryl.h>
#include <beryl_ipcs.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <beryl-private.h>

static const IPCS_Type IPCSTypes[] = {
      {"BOOL", sizeof(Bool)}
      ,
      {"UCHAR", sizeof(unsigned char)},
      {"INT", sizeof(int)},
      {"CHAR", sizeof(char)},
      {"UINT", sizeof(unsigned int)},
      {"SHORT", sizeof(short)},
      {"USHORT", sizeof(unsigned short)},
      {"LONG", sizeof(long)},
      {"ULONG", sizeof(unsigned long)},
      {"FLOAT", sizeof(float)},
      {"DOUBLE", sizeof(double)},
      {"CPTR", sizeof(char *)},
      {"VPTR", sizeof(void *)},
};

Bool IPCS_lock = FALSE;

#define CHECK_LOCK if (IPCS_lock) { fprintf(stderr,"[IPCS]: Unable to change values during paint operations!\n"); return; }
#define CHECK_LOCK_ERR if (IPCS_lock) { fprintf(stderr,"[IPCS]: Unable to change values during paint operations!\n"); return -1; }
#define UNPACK_ATOM int type=(*atoms)[valueAtom].type, pos=(*atoms)[valueAtom].pos

static void IPCSresize(unsigned int *size, unsigned char **data, int pos)
{
      if (pos <= *size)
            return;
      *data = realloc(*data, pos);
      bzero((*data) + (*size), pos - (*size));
      *size = pos;
}

int IPCS_GetType(char *type)
{
      int i;

      for (i = 0; i < (sizeof(IPCSTypes) / sizeof(IPCS_Type)); i++)
      {
            if (!strcasecmp(type, IPCSTypes[i].name))
                  return i;
      }
      return 0;
}

int IPCS_GetAtom(IPCS_OBJ, int type, char *name, Bool create)
{
      int i;

      //look for existing atom
      for (i = 0; i < *atom_count; i++)
      {
            if ((*atoms)[i].type == type && !strcasecmp((*atoms)[i].name, name))
                  return i;
      }
      //no existing atom
      if (create)
      {
            CHECK_LOCK_ERR;
            *atoms = realloc(*atoms, sizeof(IPCS_Atom) * (*atom_count + 1));
            (*atoms)[*atom_count].name = strdup(name);
            (*atoms)[*atom_count].type = type;
            if (*atom_count > 0)
                  (*atoms)[*atom_count].pos =
                              (*atoms)[*atom_count - 1].pos +
                              IPCSTypes[(*atoms)[*atom_count - 1].type].size + 1;
            else
                  (*atoms)[*atom_count].pos = 0;
            *atom_count = *atom_count + 1;
            return *atom_count - 1;
      }
      return -1;
}

// is the value set?
Bool IPCS_IsSet(IPCS_OBJ, int valueAtom)
{
      if (valueAtom < 0)
            return FALSE;
      UNPACK_ATOM;
      type = 0;                           // compiler warning stupidity
      if (pos >= (*size))
            return FALSE;
      Bool *block = (Bool *) ((*data) + pos);

      return (*block);
}

Bool IPCS_IsSetN(IPCS_OBJ, int type, char *name)
{
      return IPCS_IsSet(size, data, atom_count, atoms,
                                IPCS_GetAtom(size, data, atom_count, atoms, type,
                                                   name, FALSE));
}


// unset the value
void IPCS_Unset(IPCS_OBJ, int valueAtom)
{
      if (valueAtom < 0)
            return;
      CHECK_LOCK;
      UNPACK_ATOM;
      type = 0;                           // compiler warning stupidity
      if (pos >= (*size))
            return;
      Bool *block = (Bool *) ((*data) + pos);

      (*block) = FALSE;
}

void IPCS_UnsetN(IPCS_OBJ, int type, char *name)
{
      IPCS_Unset(size, data, atom_count, atoms,
                     IPCS_GetAtom(size, data, atom_count, atoms, type, name,
                                          FALSE));
}

#define IPCS_GEN_FUNCTIONS(ctype,itype,ipcs_type)                          \
    void IPCS_Set ## itype (IPCS_OBJ,int valueAtom, ctype value)            \
    {                                                                      \
        if (valueAtom < 0)                                                 \
            return;                                                        \
        CHECK_LOCK;                                                        \
        UNPACK_ATOM;                                                       \
        if (type != ipcs_type)                                             \
    {                                                                      \
        fprintf (stderr, "[IPCS]: Wrong data type\n");                     \
        return;                                                            \
    }                                                                      \
        if (pos + sizeof (ctype) + 1 >= (*size))                           \
            IPCSresize (size, data, pos + sizeof (ctype)+1);               \
        Bool *block = (Bool *) ((*data) + pos);                            \
        ctype *val = (ctype *) ((*data) + pos + 1);                        \
        (*block) = TRUE;                                                   \
        (*val) = value;                                                    \
    }                                                                      \
                                                                           \
    void IPCS_Set ## itype ## N (IPCS_OBJ,char * name, ctype value)        \
    {                                                                      \
        IPCS_Set ## itype (size,data,atom_count,atoms,                     \
        IPCS_GetAtom (size,data,atom_count,atoms, ipcs_type, name, FALSE), \
        value);                                                            \
    }                                                                      \
                                                                           \
    ctype IPCS_Get ## itype (IPCS_OBJ,int valueAtom)                       \
    {                                                                      \
        if (valueAtom < 0)                                                 \
            return 0;                                                      \
        UNPACK_ATOM;                                                       \
        if (type != ipcs_type)                                             \
        {                                                                  \
            fprintf (stderr, "[IPCS]: Wrong data type\n");                 \
            return 0;                                                      \
        }                                                                  \
        if ((pos + 1) > (*size) || !IPCS_IsSet (IPCS_OBJNAMES, valueAtom)) \
            return 0;                                                      \
        ctype *block = (ctype *) ((*data) + pos + 1);                      \
        return (*block);                                                   \
    }                                                                      \
                                                                           \
    ctype IPCS_Get ## itype ## N (IPCS_OBJ,char * name)                    \
    {                                                                      \
        return IPCS_Get ## itype (size,data,atom_count,atoms,              \
        IPCS_GetAtom (size,data,atom_count,atoms, ipcs_type, name, FALSE));\
    }                                                                      \
                                                                           \
    ctype IPCS_Get ## itype ## D (IPCS_OBJ,int valueAtom, ctype def)       \
    {                                                                      \
        if (valueAtom < 0)                                                 \
            return def;                                                    \
        UNPACK_ATOM;                                                       \
        if (type != ipcs_type)                                             \
        {                                                                  \
            fprintf (stderr, "[IPCS]: Wrong data type\n");                 \
            return def;                                                    \
        }                                                                  \
        if ((pos + 1) > (*size) || !IPCS_IsSet (IPCS_OBJNAMES, valueAtom)) \
            return def;                                                    \
        ctype *block = (ctype *) ((*data) + pos + 1);                      \
        return (*block);                                                   \
    }                                                                      \
                                                                           \
    ctype IPCS_Get ## itype ## ND (IPCS_OBJ,char * name , ctype def)       \
    {                                                                      \
        return IPCS_Get ## itype ## D (size,data,atom_count,atoms,         \
        IPCS_GetAtom (size,data,atom_count,atoms, ipcs_type, name, FALSE), \
        def);                                                              \
    }                                                                      \


IPCS_GEN_FUNCTIONS(Bool, Bool, IPCS_BOOL)
IPCS_GEN_FUNCTIONS(unsigned char, UChar, IPCS_UCHAR)
IPCS_GEN_FUNCTIONS(int, Int, IPCS_INT)
IPCS_GEN_FUNCTIONS(char, Char, IPCS_CHAR)
IPCS_GEN_FUNCTIONS(unsigned int, UInt, IPCS_UINT)
IPCS_GEN_FUNCTIONS(short, Short, IPCS_SHORT)
IPCS_GEN_FUNCTIONS(unsigned short, UShort, IPCS_USHORT)
IPCS_GEN_FUNCTIONS(long, Long, IPCS_LONG)
IPCS_GEN_FUNCTIONS(unsigned long, ULong, IPCS_ULONG)
IPCS_GEN_FUNCTIONS(float, Float, IPCS_FLOAT)
IPCS_GEN_FUNCTIONS(double, Double, IPCS_DOUBLE)
IPCS_GEN_FUNCTIONS(char *, CPtr, IPCS_CPTR)
IPCS_GEN_FUNCTIONS(void *, VPtr, IPCS_VPTR)

Generated by  Doxygen 1.6.0   Back to index