// -*- C++ -*-
/* ======================================================================= *\
    File   : kbmap.h, kbmap.h,v 1.1.1.1 1996/08/19 14:39:26 larsbj Exp
    Author : chb, 30.Oct.1995
    Docu   : see kbmap.C
    Purpose: class definitions for XKeyEvent keymap handling
\* ======================================================================= */

#ifndef _KBMAP_H_
#define _KBMAP_H_

#include <X11/Xlib.h>

#define KB_PREALLOC  16
#define KB_HASHSIZE 128   // yes, yes - I know. 128 is not exactly prime :-)
                          // ... but we are dealing with ASCII chars mostly.


class kb_keymap;
class kb_sequence;


typedef struct
{
   unsigned   code;                     // keysym
   unsigned   mod;                      // modifier masks
   kb_keymap *table;                    // keymap for prefix keys
   int        action;                   // action for !prefix keys
} kb_key;


/* ---F+------------------------------------------------------------------ *\
    Class     : kb_keymap
    Purpose   : define key maps and actions for key sequences
    Variables : size   - table size
                table  - list of kb_key structs holding the defined keys
                htable - hash table containing key lists
    Methods   : defkey - define a new key sequence
                lookup - look up a key in the keymap
\* ---F------------------------------------------------------------------- */

class kb_keymap
{
 public:

   // --- variables -------------------------------------------------------

   int         size;                    // size of the table (<0: hashtab)
   union
   {
      kb_key  *table;                   // table for linear array
      kb_key **htable;                  // hash table
   };

 public:

   // --- methods ---------------------------------------------------------

   int defkey(kb_sequence *seq, int action, int idx = 0);
   int lookup(KeySym key, unsigned mod, kb_sequence *seq);
   int bind(char *seq, int action);
   int print(char* buf, int maxlen) const;
       
 public:

   // --- c & d -----------------------------------------------------------

   kb_keymap() { size = 0; table = 0; }
  ~kb_keymap();
};


/* ---F+------------------------------------------------------------------ *\
    Class     : kb_sequence
    Purpose   : hold a key sequence and the current and standard keymaps
    Variables : stdmap - keymap to use if a new sequence is starting
                curmap - keymap to use for the next key
                sequence  - array holding the current key sequence
                staticseq - static array preallocated for sequence
                length    - current length of key sequence
                size      - physically allocated storage size
    Methods   : addkey - add a key to the key sequence and look it up
                         in the curmap if the latter is defined
                delseq - make length negative to mark the sequence as
                         deleted
    Note      : if sequence[length-1] < 0xff it can be used as ISO8895 char
\* ---F------------------------------------------------------------------- */

class kb_sequence
{
 public:

   // --- variables -------------------------------------------------------

   kb_keymap *stdmap;
   kb_keymap *curmap;

   unsigned  *sequence;
   unsigned  *modifiers;
   unsigned   staticseq[KB_PREALLOC];
   unsigned   staticmod[KB_PREALLOC];
   int        length, size;

 public:

   // --- methods ---------------------------------------------------------

   int  addkey(KeySym key, unsigned mod, unsigned nmod = 0);
   int  parse(char *s);
   int  print(char *buf, int maxlen, bool when_defined = false) const; //RVDK_PATCH_5
   int  printOptions(char *buf, int maxlen) const;
   void delseq();
   char getiso();
   KeySym getsym();
   void reset(void);                                // RVDK_PATCH_5

 public:

   // --- c & d -----------------------------------------------------------

   kb_sequence()
   {
      stdmap = curmap = 0;
      sequence = staticseq;
      modifiers = staticmod;
      length = 0; size = KB_PREALLOC;
   }
  ~kb_sequence()
   {
      if(sequence != staticseq)
      {
         delete sequence;
         delete modifiers;
      }
   }
};


inline
int kb_keymap::bind(char *seq, int action)
{
   kb_sequence k;

   int res = k.parse(seq);
   if (!res) 
     defkey(&k, action); 
   k.delseq();
   return res;
}


#endif /* _KBMAP_H_ */

/* === End of File: kbmap.h ============================================== */
