/* $Id: mymap.c,v 3.1 1994/02/25 02:33:38 ppessi Exp $
 *
 * keymap.c --- a (Finnish) keymap for my taste
 *
 * Author: ppessi <Pekka.Pessi@hut.fi>
 *
 * Copyright © 1993 Pekka Pessi
 *
 * Created      : Fri Apr  2 01:13:20 1993 ppessi
 * Last modified: Fri Feb 25 02:09:39 1994 ppessi
 *
 * Compile with gcc: gcc -o ss -nostdlib -DKEYMAPNAME=ss mymap.c 
 * Compile with sc : sc resopt link to ss batch Nostartup stripdebug smalldata +
 *                   DEF KEYMAPNAME=ss stringmerge data=FAR mymap.c
 * DICE does not handle this kludge.
 *
 * When compiling you will get a gazillion of warnings. Ignore them.
 *
 * Note that KEYMAPNAME *MUST* be same as 
 * the seglist file in devs:keymaps/ directory. 
 */

#include <devices/keymap.h>

#ifndef KEYMAPNAME
#define KEYMAPNAME "mymap"
#endif

extern UBYTE KeyMapName[];
extern UBYTE LoKeyMapTypes[64];
extern ULONG LoKeyMap[64];
extern UBYTE LoCapsable[8];
extern UBYTE LoRepeatable[8];
extern UBYTE HiKeyMapTypes[64];
extern ULONG HiKeyMap[64];
extern UBYTE HiCapsable[8];
extern UBYTE HiRepeatable[8];

struct KeyMapNode s =
{
  { NULL, NULL, 0, 0, KeyMapName },
  {
    LoKeyMapTypes,
    LoKeyMap,
    LoCapsable,
    LoRepeatable,
    HiKeyMapTypes,
    HiKeyMap,
    HiCapsable,
    HiRepeatable
  }
};

#define KCF_SHIFT_STRING KCF_STRING|KCF_SHIFT
#define KCF_SHIFT_CONTROL KCF_SHIFT|KCF_CONTROL
#define CSI "\233"

/* Notice byte sex */
/* c1 == plain, c2 == shifted, c3 == alt, c4 == shift+alt */
#define VANILJA(c1, c2, c3, c4) \
  ((((c4)&0xff)<<24)|(((c3)&0xff)<<16)|(((c2)&0xff)<<8)|((c1)&0xff))
/* Notice bit sex */
#define BITS(b0, b1, b2, b3, b4, b5, b6, b7) \
  (((b0)&1)<<0|((b1)&1)<<1|((b2)&1)<<2|((b3)&1)<<3| \
   ((b4)&1)<<4|((b5)&1)<<5|((b6)&1)<<6|((b7)&1)<<7)

#define DEAD(name, d1, d2, c1, c2) \
  static struct { char ded[8]; } name = \
  { DPF_DEAD, d1, DPF_DEAD, d2, 0, c1, 0, c2 }
#define ALTDEAD(name, d1, c, C) \
  static struct { char ded[16]; } name = { 0, c, 0, C, DPF_DEAD, d1, DPF_DEAD, d1, \
		     0, c & 0x1f, 0, c & 0x1f, \
		     0, c & 0x1f | 0x80, 0, c & 0x1f | 0x80 }
/* m and M are 6 chars long */
#define ACCENTED(name, c, m, M, a, A) \
  static struct { char normal[16]; char low[6]; char hi[6]; } \
  name = {{ DPF_MOD, 16, DPF_MOD, 22, \
	   0, m, 0, M, 0, c & 0x1f, 0, c & 0x1f, \
	   0, c & 0x1f | 0x80, 0, c & 0x1f | 0x80 }, a , A }

#define strsize(s) (sizeof(s)-1)

#define STRING(name, len, s) \
  static  struct { char offsets[2]; char st[len]; } \
  name = { {len, 2}, s }

#define STRING_S(name, l, s, sl, ss) \
  static struct { char offsets[4]; char st[l]; char sts[sl]; } \
  name = { {l, 4, sl, 4+l }, s, ss }

#define STRING_SA(name, l, s, sl, ss, al, sa, asl, sas) \
  static struct { char offsets[8]; \
		  char st[l]; char sts[sl]; char sta[al]; char stas[asl]; } \
  name = { {l, 8, sl, 8+l, al, 8+l+sl, asl, 8+l+sl+al }, s, ss, sa, sas }

UBYTE LoKeyMapTypes[64] =
{
  /* `~       1!                 2"          3#   */
  KC_VANILLA, KCF_SHIFT|KCF_ALT, KC_VANILLA, KCF_SHIFT|KCF_ALT,
  /* 4$ 5% ; 6& ; 7/ */
  KCF_SHIFT|KCF_ALT, KCF_SHIFT|KCF_ALT, KC_VANILLA, KCF_SHIFT|KCF_ALT,
  /* 8( 9) 0= +? */
  KCF_SHIFT|KCF_ALT, KCF_SHIFT|KCF_ALT, KCF_SHIFT|KCF_ALT, KC_VANILLA,
  /* ´` \| nil p0 */
  KCF_DEAD|KCF_SHIFT|KCF_ALT, KC_VANILLA, KCF_NOP, KC_NOQUAL,
  /* qQ wW eE rR */
  KC_VANILLA, KC_VANILLA, KCF_DEAD+KC_VANILLA, KC_VANILLA,
  /* tT yY uU iI */
  KC_VANILLA, KCF_DEAD|KC_VANILLA, KCF_DEAD|KC_VANILLA, KCF_DEAD|KC_VANILLA,
  /* oO pP åÅ ¨^ */
  KCF_DEAD|KC_VANILLA, KC_VANILLA, KC_VANILLA, KCF_DEAD|KC_VANILLA,
  /* nil p1 p2 p3 */
  KCF_NOP, KC_NOQUAL, KC_NOQUAL, KC_NOQUAL,
  /* aA sS dD fF */
  KCF_DEAD|KC_VANILLA, KC_VANILLA, KC_VANILLA, KCF_DEAD|KC_VANILLA,
  /* gG hH jJ kK */
  KCF_DEAD|KC_VANILLA, KCF_DEAD|KC_VANILLA,
  KCF_DEAD|KC_VANILLA, KCF_DEAD|KC_VANILLA,
  /* lL öÖ äÄ \'* */
  KC_VANILLA, KCF_SHIFT|KCF_ALT, KCF_SHIFT|KCF_ALT, KCF_SHIFT_STRING|KCF_ALT,
  /* nil p4 p5 p6 */
  KCF_NOP, KC_NOQUAL, KC_NOQUAL, KC_NOQUAL,
  /* <> zZ xX cC */
  KC_VANILLA, KC_VANILLA, KC_VANILLA, KC_VANILLA,
  /*  vV bB nN mM */
  KC_VANILLA, KC_VANILLA, KCF_DEAD|KC_VANILLA, KC_VANILLA,
  /* ,;	 .: -_ nil */
  KCF_SHIFT|KCF_ALT, KCF_SHIFT|KCF_ALT, KC_VANILLA, KCF_NOP,
  /* p. p7 p8 p9 */
  KC_NOQUAL, KC_NOQUAL, KC_NOQUAL, KC_NOQUAL
};

/* Dead keys */
DEAD(key0C, 1, 2, '=', '+'); /* ´` accents */
DEAD(key1B, 5, 3, ']', '}'); /* ¨^ accents */
ALTDEAD(key23, 1, 'f', 'F'); /* ´ */
ALTDEAD(key24, 2, 'g', 'G'); /* ` */
ALTDEAD(key25, 3, 'h', 'H'); /* ^ */
ALTDEAD(key26, 4, 'j', 'J'); /* ~ */
ALTDEAD(key27, 5, 'k', 'K'); /* ¨ */

/* Deadable keys */
ACCENTED(key12, 'e', '©', '©', "eéèêeë", "EÉÈÊEË");
ACCENTED(key15, 'y', '¤', '¥', "yýyyyÿ", "YÝYYYY");
ACCENTED(key16, 'u', 'µ', 'µ', "uúùûuü", "UÚÙÛUÜ");
ACCENTED(key17, 'i', '¡', '¦', "iíìîiï", "IÍÌÎIÏ");
ACCENTED(key18, 'o', 'ø', 'Ø', "oóòôõö", "OÓÒÔÕÖ");
ACCENTED(key20, 'a', 'æ', 'Æ', "aáàâãä", "AÁÀÂÃÄ");
ACCENTED(key36, 'n', '­', '¯', "nnnnñn", "NNNNÑN");
/* space bar, no alt, no control */
struct { char mod[4]; char low[6]; } key40 =
{ { DPF_MOD, 4, 0, '\240'}, " ´`^~¨" };
/* Special key for #? */
STRING_SA(key2B, 1, "\'", 1, "*", 2, "#?", 2, "[]");
/* String keys */
STRING(key5F, 3, CSI"?~");         /* Help */
STRING_S(key42, 1, "\t", 2, CSI"Z");	/* tabulator */
/* Cursor keys */
STRING_S(key4C, 2, CSI"A", 2, CSI"T"); /* up */
STRING_S(key4D, 2, CSI"B", 2, CSI"S"); /* down */
STRING_S(key4E, 2, CSI"C", 2, CSI"@"); /* right */
STRING_S(key4F, 2, CSI"D", 2, CSI"A"); /* left */
/* Function keys */
STRING_S(key50, 3, CSI"0~", 4, CSI"10~");
STRING_S(key51, 3, CSI"1~", 4, CSI"11~");
STRING_S(key52, 3, CSI"2~", 4, CSI"12~");
STRING_S(key53, 3, CSI"3~", 4, CSI"13~");
STRING_S(key54, 3, CSI"4~", 4, CSI"14~");
STRING_S(key55, 3, CSI"5~", 4, CSI"15~");
STRING_S(key56, 3, CSI"6~", 4, CSI"16~");
STRING_S(key57, 3, CSI"7~", 4, CSI"17~");
STRING_S(key58, 3, CSI"8~", 4, CSI"18~");
STRING_S(key59, 3, CSI"9~", 4, CSI"19~");

ULONG LoKeyMap[64] =
{
  VANILJA('`','~','`','~'), VANILJA('1','!','¹','¹'),
  VANILJA('2','"','@','²'), VANILJA('3','#','³','³'),
  VANILJA('4','$','¢','¤'), VANILJA('5','%','¼','%'),
  VANILJA('6','&','½','^'), VANILJA('7','/','¾','&'),
  VANILJA('8','(','·','*'), VANILJA('9',')','«','('),
  VANILJA('0','=','»',')'), VANILJA('+','?','-','_'),
  (ULONG)&key0C,            VANILJA('\\','|','\\','|'),
  0,                       '0',
  VANILJA('q','Q','å','Å'), VANILJA('w','W','°','°'),
  (ULONG)&key12,            VANILJA('r','R','®','®'),
  VANILJA('t','T','þ','Þ'), (ULONG)&key15, /* '¥¤Yy' */
  (ULONG)&key16,            (ULONG)&key17,
  (ULONG)&key18,            VANILJA('p','P','¶','¶'),
  VANILJA('å','Å','[','{'), (ULONG)&key1B,
  0L, '1', '2', '3',
  (ULONG)&key20,            VANILJA('s','S','ß','§'),
  VANILJA('d','D','ð','Ð'), (ULONG)&key23,
  (ULONG)&key24, (ULONG)&key25, (ULONG)&key26, (ULONG)&key27,
  VANILJA('l','L','£','£'), VANILJA('ö','Ö',';',':'),
  VANILJA('ä','Ä','\'','"'), (ULONG)&key2B,
  0, '4', '5', '6',
  VANILJA('<','>','\\','|'),VANILJA('z','Z','±','¬'),
  VANILJA('x','X','×','÷'), VANILJA('c','C','ç','Ç'),
  VANILJA('v','V','ª','ª'), VANILJA('b','B','º','º'),
  (ULONG)&key36,            VANILJA('m','M','¸','¿'),
  VANILJA(',',';',',','<'), VANILJA('.',':','.','>'),
  VANILJA('-','_','/','?'),  0L,
  '.', '7', '8', '9'
};

UBYTE LoCapsable[8] =
{
  /*    `  1  2  3  4  5  6  7 */
  BITS( 0, 0, 0, 0, 0, 0, 0, 0 ),
  /*    8  9  0  + \´  \ NL p0 */
  BITS( 0, 0, 0, 0, 0, 0, 0, 0 ),
  /*    q  w  e  r  t  y  u  i */
  BITS( 1, 1, 1, 1, 1, 1, 1, 1 ),
  /*    o  p  å  ¨ NL p1 p2  3 */
  BITS( 1, 1, 1, 0, 0, 0, 0, 0 ),
  /*    a  s  d  f  g  h  j  k */
  BITS( 1, 1, 1, 1, 1, 1, 1, 1 ),
  /*    l  ö  ä  ' NL p4 p5  6 */
  BITS( 1, 1, 1, 0, 0, 0, 0, 0 ),
  /*    <  z  x  c  v  b  n  m */
  BITS( 0, 1, 1, 1, 1, 1, 1, 1 ),
  /*    ,  .  - NL p. p7 p8  9 */
  BITS( 0, 0, 0, 0, 0, 0, 0, 0 )
};

UBYTE LoRepeatable[8] =
{
  /*    `  1  2  3  4  5  6  7 */
  BITS( 1, 1, 1, 1, 1, 1, 1, 1 ),
  /*    8  9  0  +  ´  \ NL  0 */
  BITS( 1, 1, 1, 1, 1, 1, 0, 1 ),
  /*    q  w  e  r  t  y  u  i */
  BITS( 1, 1, 1, 1, 1, 1, 1, 1 ),
  /*    o  p  å  ¨ NL p1 p2  3 */
  BITS( 1, 1, 1, 1, 0, 1, 1, 1 ),
  /*    a  s  d  f  g  h  j  k */
  BITS( 1, 1, 1, 1, 1, 1, 1, 1 ),
  /*    l  ö  ä  ' NL p4 p5  6 */
  BITS( 1, 1, 1, 1, 0, 1, 1, 1 ),
  /*    <  z  x  c  v  b  n  m */
  BITS( 1, 1, 1, 1, 1, 1, 1, 1 ),
  /*    ,  .  - NL p. p7 p8  9 */
  BITS( 1, 1, 1, 0, 1, 1, 1, 1 )
};

UBYTE HiKeyMapTypes[64] =
{
  /* SPACE BACKSPACE TAB ENTER */
  KCF_DEAD|KCF_ALT, KC_NOQUAL, KCF_SHIFT_STRING, KC_NOQUAL,
  /* RETURN ESCAPE DELETE nil */
  KCF_CONTROL, KCF_ALT, KCF_CONTROL, KCF_NOP,
  /* nil nil p- nil */
  KCF_NOP, KCF_NOP, KC_NOQUAL, KCF_NOP,
  /* UP DOWN RIGHT LEFT  */
  KCF_SHIFT_STRING, KCF_SHIFT_STRING, KCF_SHIFT_STRING, KCF_SHIFT_STRING,
  /* F1  F2 F3 F4 */
  KCF_SHIFT_STRING, KCF_SHIFT_STRING, KCF_SHIFT_STRING, KCF_SHIFT_STRING,
  /* F5 F6 F7 F8 */
  KCF_SHIFT_STRING, KCF_SHIFT_STRING, KCF_SHIFT_STRING, KCF_SHIFT_STRING,
  /* F9  F10 [{ ]} */
  KCF_SHIFT_STRING, KCF_SHIFT_STRING, KCF_SHIFT_CONTROL, KCF_SHIFT_CONTROL,
  /* p/ p* p+ HELP */
  KC_NOQUAL, KC_NOQUAL, KC_NOQUAL, KCF_STRING,
  /* Left Shift Right ShiCaps LockControl  ft  */
  KCF_NOP, KCF_NOP, KCF_NOP, KCF_NOP,
  /* Left Alt Right Alt Left AmigaRight Amiga  */
  KCF_NOP, KCF_NOP, KCF_NOP, KCF_NOP,
  /* Rest are all nils */
  KCF_NOP, KCF_NOP, KCF_NOP, KCF_NOP,
  KCF_NOP, KCF_NOP, KCF_NOP, KCF_NOP,
  KCF_NOP, KCF_NOP, KCF_NOP, KCF_NOP,
  KCF_NOP, KCF_NOP, KCF_NOP, KCF_NOP
};

ULONG HiKeyMap[64] =
{
  (ULONG)&key40, VANILJA('\b',0,0,0), (ULONG)&key42, VANILJA('\r',0,0,0),
  VANILJA('\r','\n',0,0), VANILJA('\033','\233', 0, 0), /* ESC CSI */
  VANILJA('\177','\037',0,0), 0L,
  0L, 0L, '-', 0L,
  (ULONG)&key4C, (ULONG)&key4D, (ULONG)&key4E, (ULONG)&key4F,
  (ULONG)&key50, (ULONG)&key51, (ULONG)&key52, (ULONG)&key53,
  (ULONG)&key54, (ULONG)&key55, (ULONG)&key56, (ULONG)&key57,
  (ULONG)&key58, (ULONG)&key59,
  VANILJA('[','{', '\033', '\033'), VANILJA(']','}', '\035', '\035'),
  '/', '*', '+', (ULONG)&key5F,
  0, 0, 0, 0, 0, 0, 0, 0,
  0, 0, 0, 0, 0, 0, 0, 0,
  0, 0, 0, 0, 0, 0, 0, 0,
  0, 0, 0, 0, 0, 0, 0, 0
};

UBYTE HiRepeatable[8] =
{
  /*   SPCBS TabEntRetEscDel NA */
  BITS( 1, 1, 1, 0, 0, 0, 1, 0 ),
  /*   NA NA p- NA Up DwnRgtLft */
  BITS( 0, 0, 1, 0, 1, 1, 1, 1 ),
  /*   F1 F2 F3 F4 F5 F6 F7 F8 */
  BITS( 1, 1, 1, 1, 1, 1, 1, 1 ),
  /*   F9F10 p[ p] p/ p* p+ LP */
  BITS( 1, 1, 0, 0, 0, 0, 0, 0 ),
  /*   60          -        67 */
  BITS( 0, 0, 0, 0, 0, 0, 0, 0 ),
  /*   68          -        6F */
  BITS( 0, 0, 0, 0, 0, 0, 0, 0 ),
  /*   70          -        77 */
  BITS( 0, 0, 0, 0, 0, 0, 0, 0 )
};

UBYTE HiCapsable[8] =
{
  /*   SPCBS TabEntRetEscDel NA */
  BITS( 0, 0, 0, 0, 0, 0, 0, 0 ),
  /*   NA NA p- NA Up DwnRgtLft */
  BITS( 0, 0, 0, 0, 0, 0, 0, 0 ),
  /*   F1 F2 F3 F4 F5 F6 F7 F8 */
  BITS( 0, 0, 0, 0, 0, 0, 0, 0 ),
  /*   F9 F10p[Fp] p/ p* p+ LP*/
  BITS( 0, 0, 0, 0, 0, 0, 0, 0 ),
  /*   60           -       67 */
  BITS( 0, 0, 0, 0, 0, 0, 0, 0 ),
  /*   68           -       6F */
  BITS( 0, 0, 0, 0, 0, 0, 0, 0 ),
  /*   70           -       77 */
  BITS( 0, 0, 0, 0, 0, 0, 0, 0 )
};

UBYTE KeyMapName[] = KEYMAPNAME;
