/* * * IRBOX, an Ivy driver for infra-red remote controls * * Copyright 1998-1999 * Centre d'Etudes de la Navigation Aerienne * * Tables for decoding events * * Authors: Stephane Chatty * * $Id$ * * Please refer to file version.h for the * copyright notice regarding this software */ #include "irtable.h" #include "irdev.h" #include #include #include typedef struct _irtablecell IrTableCell; struct _irtablecell { IrTable* table; unsigned char code[6]; const char* key; IrTableCell* next; }; #define KEYCELLS 127 #define CODECELLS 1023 static IrTableCell* KeyToCell [KEYCELLS]; static IrTableCell* CodeToCell [CODECELLS]; static int Initialized = 0; IrTable* IrCreateTable () { if (!Initialized) { Initialized = 1; memset (KeyToCell, 0, sizeof (KeyToCell)); memset (CodeToCell, 0, sizeof (CodeToCell)); } return (IrTable*) malloc (sizeof (IrTable)); } void IrTableName (IrTable* t, const char* n) { t->name = strdup (n); } void IrTableType (IrTable* t, const char* type) { t->type = strdup (type); } void IrTableAddBrand (IrTable* t, const char* b) { } static unsigned int IrHashKey (const char* key) { register unsigned int h = 0; register const char* p = key; while (*p) h += (h << 3) + *p++; /* this hash function was stolen from Tcl */ return h % KEYCELLS; } static unsigned int IrHashCode (const unsigned char* code) { register unsigned int h = 0; register const unsigned char* p = code; register const unsigned char* q = p+6; while (p < q) h += (h << 3) + *p++; /* A ADAPTER */ return h % CODECELLS; } void IrTableAddKey (IrTable* t, const char* k, int c0, int c1, int c2, int c3 , int c4, int c5) { IrTableCell* c = (IrTableCell*) malloc (sizeof (IrTableCell)); IrTableCell** cc; IrTableCell* p; c->table = t; c->code[0] = c0; c->code[1] = c1; c->code[2] = c2; c->code[3] = c3; c->code[4] = c4; c->code[5] = c5; cc = CodeToCell + IrHashCode (c->code); /* collision handling */ p = *cc; while (p) { if (strncmp (p->code, c->code, 6) == 0) { fprintf (stderr, "Code for key \'%s\' on %s", k, t->name); fprintf (stderr, " was already registered"); fprintf (stderr, " for key \'%s\' on %s\n", p->key, p->table->name); free (c); return; } p = p->next; } /* fine, we can keep on storing that key */ c->key = strdup (k); c->next = *cc; *cc = c; } int IrTableTranslateCode (const unsigned char* code, IrTable** table, const char** key) { IrTableCell* c; c = CodeToCell [IrHashCode (code)]; while (c) { if (strncmp (code, c->code, 6) == 0) break; c = c->next; } if (c) { if (table) *table = c->table; if (key) *key = c->key; } else { if (table) *table = 0; if (key) *key = 0; } return (int) (c); } void IrResetTables (void) { #if 0 /* THIS CODE TRIGGERS A MEMORY BUG */ /* WE'LL SEE TO THAT LATER */ /* free all cells in hash tables */ if (Initialized) { /* erase hash tables */ IrTableCell** cc; for (cc = CodeToCell; cc < CodeToCell + CODECELLS; ++cc) { IrTableCell* c = *cc; while (c) { IrTableCell* old = c; c = c->next; free ((char*) old->key); free (old); } } for (cc = KeyToCell; cc < KeyToCell + CODECELLS; ++cc) { IrTableCell* c = *cc; while (c) { IrTableCell* old = c; c = c->next; free ((char*) old->key); free (old); } } } #endif /* initialize hash tables to zero */ Initialized = 1; memset (KeyToCell, 0, sizeof (KeyToCell)); memset (CodeToCell, 0, sizeof (CodeToCell)); /* should also free tables */ } void IrReadTables (const char* dirname) { char indexname[512]; char filebuf [512]; char absfilebuf [1024]; FILE* index; int res; int nbline = 0; strcpy (indexname, dirname); strcat (indexname, "/tables.dir"); index = fopen (indexname, "r"); if (!index) { char errmsg [1024]; sprintf (errmsg, "Cannot open index file %s", indexname); perror (errmsg); fprintf (stderr, "No table loaded\n"); return; } /* scan index file, and launch parsing of every file listed in the index */ while ((res = fscanf (index, "%512s", filebuf)) != EOF) { ++nbline; if (!res) { fprintf (stderr, "Malformatted line in %s, line %d:\n", indexname, nbline); continue; } strcpy (absfilebuf, dirname); strcat (absfilebuf, "/"); strcat (absfilebuf, filebuf); IrTableReadFile (absfilebuf); } }