/*
 * lsadb.h, needed by lsadb.c
 * Copyright 2001-2005 by Matthias Grimm
 *
 * 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; either version
 * 2 of the License, or (at your option) any later version.
 *
 * Please be so kind to send me a copy of your modifications to
 *      Matthias Grimm <matthiasgrimm@users.sourceforge.net>
 *
 * Thanks to Jimi Xenidis for his programm fnset.c
*/

#define PACKAGE		"lsadb"
#define VERSION		"0.1.3"

/* short options for optarg */
#define ARG_ALL			"hv"
#define ARG_HELP		'h'
#define ARG_VERSION		'v'

void regx_raw(unsigned char data[]);
void reg0_stdkbd(unsigned char data[]);
void reg1_pbg3kbd(unsigned char data[]);
void reg2_stdkbd(unsigned char data[]);

void reg1_extmouse(unsigned char data[]);

/* ------------------------ */

enum KBDLayout { none, unknown=0, domestic, iso, japanese }; /* existing keyboard layouts */

const char *kbdlayouts[] = {
    "",
    "(domestic layout)",
    "(ISO layout)",
    "(japanese layout)"
};

/* Definition of one ADB device. The two first integers identify the device.
   There is no dynamic function to decode register 3 because this register is well
   defined through Apple and identically for all devices. */
   
struct ADBDev {
    int	 	   devicetype;
    int	 	   handler_id;
    char 	   *name;
    enum KBDLayout layout;
    void (*REG0_decode)(unsigned char data[]);
    void (*REG1_decode)(unsigned char data[]);
    void (*REG2_decode)(unsigned char data[]);
};

struct adbreg0_stdkbd {
    unsigned int   keyup0:1;        /* Key pressed/released */
    unsigned int   keycode0:7;      /* Scancode */
    unsigned int   keyup1:1;
    unsigned int   keycode1:7;
};

struct adbreg1_pbg3kbd {
    unsigned int   :8;		    /* unknown, perhaps keboard revision */
    unsigned int   :7;		    /* unknown, perhaps flags */
    unsigned int   primfkeys:1;     /* primary function keys */
};

struct adbreg2_stdkbd {
    unsigned int   fnkey:1;	    /* Fn key pressed */
    unsigned int   deletekey:1;     /* Delete pressed */
    unsigned int   capslockkey:1;   /* Caps Lock pressed */
    unsigned int   resetkey:1;      /* Reset pressed */ 
    unsigned int   controlkey:1;    /* Control pressed */
    unsigned int   shiftkey:1;      /* Shift pressed */
    unsigned int   optionkey:1;     /* Option key pressed */
    unsigned int   applekey:1;      /* Apple/command key pressed */
    unsigned int   numlockkey:1;    /* Num Lock presed */
    unsigned int   scrolllockkey:1; /* Scroll Lock pressed */
    unsigned int   reserved:3;
    unsigned int   scrolllockled:1; /* Scroll Lock LED on */
    unsigned int   capslockled:1;   /* Caps Lock LED on */
    unsigned int   numlockled:1;    /* Num Lock LED on */
};

struct adbreg3 {
    unsigned int   :1;		    /* always zero */
    unsigned int   exev:1;	    /* Exeptional Event */
    unsigned int   sre:1;	    /* Service Request Enable */
    unsigned int   :1;		    /* reserved */
    unsigned int   devtype:4;	    /* device address */
    unsigned int   devhandler:8;    /* device handler id */
};

const char *devicetypes[] = {
 /*  0 */ "Computer",
 /*  1 */ "Protection Device",
 /*  2 */ "Encode Device",
 /*  3 */ "Relative-Position Device",
 /*  4 */ "Absolute-Position Device",
 /*  5 */ "Data Transfer Device",
 /*  6 */ "Reserved",
 /*  7 */ "Misc. Device",	
 /*  8 */ "Couldn't investigate device type, device was shifted",
 /*  9 */ "Couldn't investigate device type, device was shifted",
 /* 10 */ "Couldn't investigate device type, device was shifted",
 /* 11 */ "Couldn't investigate device type, device was shifted",
 /* 12 */ "Couldn't investigate device type, device was shifted",
 /* 13 */ "Couldn't investigate device type, device was shifted",
 /* 14 */ "Couldn't investigate device type, device was shifted",
 /* 15 */ "Couldn't investigate device type, device was shifted"
}; 

#define MAXDEVICECLASS 3   /* count of classes definitions in the following array */

const char *deviceclasses[] = {
         "Unknown",
 /* 0 */ "Tablet (absolute)",
 /* 1 */ "Mouse",
 /* 2 */ "Trackball",
 /* 3 */ "Trackpad"
};

/* The high bit of the trackpad deviceclass is a program mode identifier. If set to 1
   reg 2 contains completely different data at next read. This shadow register needs
   to be implemented in lsadb */

/* unsolved keyboard riddles:
   1. In Apple technote hw/hw_01.html you can find the following keyboard definition:
        "259 Small Macintosh 512K Keyboard (no keypad; ISO layout)"
      This is an impossible Handler ID because there is only one Byte defined for that information.

   2. Regarding the Document ADBManager from Apple support the Apple Extended Keyboard (Device ID 0x02)
      also the Handler ID 0x03. Switched to that ID is would send seperate Keycodes for left and right
      shift keys. This collides with the following description for Handler ID 0x03, found in several
      documents from developer.apple.com.
*/   

#define ADB_DUMMY 0   /* supplement to definitions in adb.h */

struct ADBDev ADBDevices[] = {
  { ADB_DUMMY   ,   0, "Unknown",                                          unknown,  regx_raw,    regx_raw,     regx_raw    },

  { ADB_KEYBOARD,   1, "Apple Keyboard or Keyboard II",                    domestic, reg0_stdkbd, regx_raw,     reg2_stdkbd },
  { ADB_KEYBOARD,   2, "Apple Extended Keyboard or Extended Keyboard II",  domestic, reg0_stdkbd, regx_raw,     reg2_stdkbd },
  { ADB_KEYBOARD,   3, "Small Macintosh 512K Keyboard without keypad",     domestic, reg0_stdkbd, regx_raw,     reg2_stdkbd },
  { ADB_KEYBOARD,   4, "Apple Standard Keyboard",                          iso,      reg0_stdkbd, regx_raw,     reg2_stdkbd },
  { ADB_KEYBOARD,   5, "Apple Extended Keyboard II",                       iso,      reg0_stdkbd, regx_raw,     reg2_stdkbd },
  { ADB_KEYBOARD,   6, "Apple Macintosh Portable Keyboard",                domestic, reg0_stdkbd, regx_raw,     reg2_stdkbd },
  { ADB_KEYBOARD,   7, "Apple Macintosh Portable Keyboard",                iso,      reg0_stdkbd, regx_raw,     reg2_stdkbd },
  { ADB_KEYBOARD,   8, "Apple Macintosh Keyboard II",                      domestic, reg0_stdkbd, regx_raw,     reg2_stdkbd },
  { ADB_KEYBOARD,   9, "Apple Macintosh Keyboard II",                      iso,      reg0_stdkbd, regx_raw,     reg2_stdkbd },
  { ADB_KEYBOARD,  11, "Macintosh Plus Keyboard with the built-in keypad", unknown,  reg0_stdkbd, regx_raw,     reg2_stdkbd },
  { ADB_KEYBOARD,  12, "Macintosh PowerBook Keyboard",                     domestic, reg0_stdkbd, regx_raw,     reg2_stdkbd },
  { ADB_KEYBOARD,  13, "Macintosh PowerBook Keyboard",                     iso,      reg0_stdkbd, regx_raw,     reg2_stdkbd },
  { ADB_KEYBOARD,  14, "Apple adjustible Keypad",                          unknown,  reg0_stdkbd, regx_raw,     reg2_stdkbd },
  { ADB_KEYBOARD,  16, "Apple adjustible Keyboard",                        domestic, reg0_stdkbd, regx_raw,     reg2_stdkbd },
  { ADB_KEYBOARD,  17, "Apple adjustible Keyboard",                        iso,      reg0_stdkbd, regx_raw,     reg2_stdkbd },
  { ADB_KEYBOARD,  18, "Apple adjustible Keyboard",                        japanese, reg0_stdkbd, regx_raw,     reg2_stdkbd },
  { ADB_KEYBOARD,  20, "Unknown Keyboard",                                 iso,      reg0_stdkbd, regx_raw,     reg2_stdkbd },
  { ADB_KEYBOARD,  21, "Unknown Keyboard",                                 japanese, reg0_stdkbd, regx_raw,     reg2_stdkbd },
  { ADB_KEYBOARD,  22, "Unknown Keyboard",                                 japanese, reg0_stdkbd, regx_raw,     reg2_stdkbd },
  { ADB_KEYBOARD,  23, "Unknown Keyboard",                                 japanese, reg0_stdkbd, regx_raw,     reg2_stdkbd },
  { ADB_KEYBOARD,  24, "Powerbook 3400 Keyboard",                          domestic, reg0_stdkbd, regx_raw,     reg2_stdkbd },
  { ADB_KEYBOARD,  25, "Unknown Keyboard",                                 iso,      reg0_stdkbd, regx_raw,     reg2_stdkbd },
  { ADB_KEYBOARD,  26, "Unknown Keyboard",                                 japanese, reg0_stdkbd, regx_raw,     reg2_stdkbd },
  { ADB_KEYBOARD,  27, "Unknown Keyboard",                                 domestic, reg0_stdkbd, regx_raw,     reg2_stdkbd },
  { ADB_KEYBOARD,  28, "Unknown Keyboard",                                 domestic, reg0_stdkbd, regx_raw,     reg2_stdkbd },
  { ADB_KEYBOARD,  29, "Unknown Keyboard",                                 iso,      reg0_stdkbd, regx_raw,     reg2_stdkbd },
  { ADB_KEYBOARD,  30, "Unknown Keyboard",                                 japanese, reg0_stdkbd, regx_raw,     reg2_stdkbd },
  { ADB_KEYBOARD, 192, "Unknown Keyboard",                                 domestic, reg0_stdkbd, regx_raw,     reg2_stdkbd },
  { ADB_KEYBOARD, 193, "Unknown Keyboard",                                 iso,      reg0_stdkbd, regx_raw,     reg2_stdkbd },
  { ADB_KEYBOARD, 194, "Unknown Keyboard",                                 japanese, reg0_stdkbd, regx_raw,     reg2_stdkbd },
  { ADB_KEYBOARD, 195, "Apple Macintosh Powerbook G3 Keyboard",            domestic, reg0_stdkbd, reg1_pbg3kbd, reg2_stdkbd },
  { ADB_KEYBOARD, 196, "Apple Macintosh PowerBook G3 Keyboard",            iso,      reg0_stdkbd, reg1_pbg3kbd, reg2_stdkbd },
  { ADB_KEYBOARD, 197, "Unknown Keyboard",                                 japanese, reg0_stdkbd, regx_raw,     reg2_stdkbd },
  { ADB_KEYBOARD, 198, "Unknown Keyboard",                                 domestic, reg0_stdkbd, regx_raw,     reg2_stdkbd },
  { ADB_KEYBOARD, 199, "Unknown Keyboard",                                 iso,      reg0_stdkbd, regx_raw,     reg2_stdkbd },
  { ADB_KEYBOARD, 200, "Unknown Keyboard",                                 japanese, reg0_stdkbd, regx_raw,     reg2_stdkbd },
  { ADB_KEYBOARD, 201, "Unknown Keyboard",                                 japanese, reg0_stdkbd, regx_raw,     reg2_stdkbd },

  { ADB_MOUSE,      1, "Standard Apple Mouse Protokoll 100 dpi",           none,     regx_raw,    regx_raw,     regx_raw    },
  { ADB_MOUSE,      2, "Standard Apple Mouse Protokoll 200 dpi",           none,     regx_raw,    regx_raw,     regx_raw    },
  { ADB_MOUSE,      4, "Extended Mouse Protokoll",                         none,     regx_raw,    reg1_extmouse,regx_raw    },

  { ADB_MISC,       2, "Adjustible Button Device",                         none,     regx_raw,    regx_raw,     regx_raw    },
  { ADB_MISC,      31, "Powerbook G3 (Pismo) Button Device",               none,     regx_raw,    regx_raw,     regx_raw    }
};


