Hi all,

appended is a quick and dirty (no optimization) standalone version of a
dumpkeylist program that would be a replacement of dumpkmap with the
following changes:

1) Use textual representation on output (not binary)
Textual keymaps are independent of CPU architecture and will not produce
incompatibilities if any definition in the kernel changes (like maximum
number of keys).

2) Allow for all key maps from 0 to 255 (detect which are available)

3) Allow for all keys from 1 to 255 (detects which are used)

4) Emit all used function key strings

5) Emit all compose key definitions
Detects if old 8 bit or new Unicode structure is used. New Unicode
structure allow for compose key definition in the range U+0000..FFFF
(old structure only 00..FF).


The emitted table is big, about 180k ... but if filtered to the tables
current dumpkmap uses and compressed using gzip the size is about 3k ...
which is not much more than the size of a current binary kmap. All
filtering can be done using simple awk or sed scripts.

Comments welcome.

--
Harald

PS: This is a prerelease version for informational purposes not to be
used in main stream!

#include <stdio.h>
#include <linux/keyboard.h>
#include <linux/kd.h>

// emit a possibly backslash escaped character
int fputc_esc( int c, FILE* file )
{
  const char* p = "\aa\bb\ff\nn\rr\tt\\\\\"\"";

  while( *p && *p != (char)c ) ++p;

  if( *p )
    return fprintf( file, "\\%c", *p );

  if( c < 0x20 || c > 0x7E )
    return fprintf( file, "\\%03o", c );

  return fputc( c, file );
}


// dump all used function key strings
static void dump_fnkey_strings( void )
{
#if defined KDGKBSENT
  unsigned int key;
  const char* p;
  struct kbsentry se;

  for( key = 0; key < MAX_NR_FUNC; ++key )
  {
    se.kb_func = key;
    if( ioctl(0,KDGKBSENT,&se) == 0
     && se.kb_string[0] != '\0'
    ) {
      fprintf( stdout, "S 0x%04X \"", K(KT_FN,key) );
      for( p = se.kb_string; *p; ++p )
        fputc_esc( *p, stdout );
      fputs( "\"\n", stdout );
    }
  }
#else
  /* empty */
#endif
}


// dump all used compose key definitions
static void dump_compose_keys( void )
{
#if defined KDGKBDIACRUC
  struct kbdiacrsuc dtuc;
  struct kbdiacruc const *deuc;
  struct kbdiacruc const *dpuc;

  if( ioctl(0,KDGKBDIACRUC,&dtuc) == 0 )
  {
    deuc = dtuc.kbdiacruc + dtuc.kb_cnt;
    for( dpuc = dtuc.kbdiacruc; dpuc < deuc; ++dpuc )
      fprintf( stdout, "C 0x%04X 0x%04X 0x%04X\n",
        dpuc->diacr, dpuc->base, dpuc->result );
  }
#elif defined KDGKBDIACR
  struct kbdiacrs dt;
  struct kbdiacr const *de;
  struct kbdiacr const *dp;

  if( ioctl(0,KDGKBDIACR,&dt) == 0 )
  {
    de = dt.kbdiacr + dt.kb_cnt;
    for( dp = dt.kbdiacr; dp < de; ++dp )
      fprintf( stdout "C 0x%04X 0x%04X 0x%04X\n",
        dp->diacr, dp->base, dp->result );
  }
#else
  /* empty */
#endif
}


// dump all active keys in available key maps
static void dump_key_definitions( void )
{
#if defined KDGKBENT
  unsigned int key;
  unsigned int mod;
  struct kbentry ke;
  unsigned char km[MAX_NR_KEYMAPS];

  // determine available keymaps
  fputc( 'M', stdout );
  for( mod = 0; mod < MAX_NR_KEYMAPS; ++mod )
  {
    ke.kb_table = mod;
    ke.kb_index = 0;
    km[mod] = ioctl(0,KDGKBENT,&ke) == 0
           && ke.kb_value != K_NOSUCHMAP;
    if( km[mod] )
      fprintf( stdout, " %u", mod );
  }
  fputc( '\n', stdout );

  // dump the key definitions
  for( key = 1; key < NR_KEYS; ++key )
    for( mod = 0; mod < MAX_NR_KEYMAPS; ++mod )
      if( km[mod] )
      {
        ke.kb_table = mod;
        ke.kb_index = key;
        if( ioctl(0,KDGKBENT,&ke) == 0
         && ke.kb_value != K_NOSUCHMAP
         && ke.kb_value != K_ALLOCATED
         && ke.kb_value != K_HOLE
      ) fprintf( stdout, "K %u %u 0x%04X\n", key, mod, ke.kb_value );
    }
#else
  /* empty */
#endif
}


int main( void )
{
  dump_key_definitions();
  dump_fnkey_strings();
  dump_compose_keys();
  return 0;
}
_______________________________________________
busybox mailing list
[email protected]
http://lists.busybox.net/mailman/listinfo/busybox

Reply via email to