/* elmo - ELectronic Mail Operator Copyright (C) 2003, 2004 rzyjontko 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; version 2. 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. ---------------------------------------------------------------------- */ /**************************************************************************** * IMPLEMENTATION HEADERS ****************************************************************************/ #include "keymap.h" #include "xmalloc.h" #include "error.h" #include "exec.h" /**************************************************************************** * IMPLEMENTATION PRIVATE DEFINITIONS / ENUMERATIONS / SIMPLE TYPEDEFS ****************************************************************************/ #define FIRST_ALLOC 10 /**************************************************************************** * IMPLEMENTATION PRIVATE CLASS PROTOTYPES / EXTERNAL CLASS REFERENCES ****************************************************************************/ /**************************************************************************** * IMPLEMENTATION PRIVATE STRUCTURES / UTILITY CLASSES ****************************************************************************/ /**************************************************************************** * IMPLEMENTATION REQUIRED EXTERNAL REFERENCES (AVOID) ****************************************************************************/ /**************************************************************************** * IMPLEMENTATION PRIVATE DATA ****************************************************************************/ static int no_default = 0; /**************************************************************************** * INTERFACE DATA ****************************************************************************/ keymap_t keymap_default; /**************************************************************************** * IMPLEMENTATION PRIVATE FUNCTION PROTOTYPES ****************************************************************************/ /**************************************************************************** * IMPLEMENTATION PRIVATE FUNCTIONS ****************************************************************************/ static void reallocate (keymap_t *km) { if (km->k_size == km->k_count){ km->k_size = (km->k_size + 1) * 2; km->keys = xrealloc (km->keys, km->k_size * sizeof (struct key)); } if (km->m_size == km->m_count){ km->m_size = (km->m_size + 1) * 2; km->meta = xrealloc (km->meta, km->m_size * sizeof (struct key)); } } static void execute (struct key *k) { exec_run (k->exec); } /**************************************************************************** * INTERFACE FUNCTIONS ****************************************************************************/ void keymap_init (keymap_t *km) { km->k_size = FIRST_ALLOC; km->k_count = 0; km->keys = xmalloc (km->k_size * sizeof (struct key)); km->m_size = FIRST_ALLOC; km->m_count = 0; km->meta = xmalloc (km->m_size * sizeof (struct key)); } void keymap_destroy (keymap_t *km) { if (km->keys) xfree (km->keys); if (km->meta) xfree (km->meta); } struct key * keymap_lookup (keymap_t *km, int key, int no_default) { int i; for (i = 0; i < km->k_count; i++){ if (km->keys[i].key == key) return km->keys + i; } if (no_default) return NULL; for (i = 0; i < keymap_default.k_count; i++){ if (keymap_default.keys[i].key == key) return keymap_default.keys + i; } return NULL; } struct key * keymap_meta_lookup (keymap_t *km, int key, int no_default) { int i; for (i = 0; i < km->m_count; i++){ if (km->meta[i].key == key) return km->meta + i; } if (no_default) return NULL; for (i = 0; i < keymap_default.m_count; i++){ if (keymap_default.meta[i].key == key) return keymap_default.meta + i; } return NULL; } struct key * keymap_lookup_fun (keymap_t *km, void (*fun)(void)) { int i; exec_t *exec = exec_lookup_fun (fun); if (exec == NULL) return NULL; for (i = 0; i < km->k_count; i++){ if (km->keys[i].exec == exec) return km->keys + i; } if (no_default) return NULL; for (i = 0; i < keymap_default.k_count; i++){ if (keymap_default.keys[i].exec == exec){ if (keymap_lookup (km, keymap_default.keys[i].key, 1)) return NULL; return keymap_default.keys + i; } } return NULL; } void keymap_add (keymap_t *km, int key, int meta, void (*fun)(void)) { struct key *k; exec_t *exec = exec_lookup_fun (fun); if (meta) k = keymap_meta_lookup (km, key, 1); else k = keymap_lookup (km, key, 1); if (k){ k->exec = exec; return; } reallocate (km); if (! meta){ km->keys[km->k_count].key = key; km->keys[km->k_count].exec = exec; km->k_count++; } else { km->meta[km->m_count].key = key; km->meta[km->m_count].exec = exec; km->m_count++; } } int keymap_action (keymap_t *km, int key, int meta) { struct key *k; if (meta) k = keymap_meta_lookup (km, key, no_default); else k = keymap_lookup (km, key, no_default); if (k){ execute (k); return 0; } return 1; } void keymap_disable_default (void) { no_default = 1; } void keymap_enable_default (void) { no_default = 0; } /**************************************************************************** * INTERFACE CLASS BODIES ****************************************************************************/ /**************************************************************************** * * END MODULE keymap.c * ****************************************************************************/