Logo Search packages:      
Sourcecode: faumachine version File versions  Download package

keyboard.c

/* $Id: keyboard.c,v 1.40 2009-01-28 12:59:20 potyra Exp $ 
 *
 * Copyright (C) 2006-2009 FAUmachine Team <info@faumachine.org>.
 * This program is free software. You can redistribute it and/or modify it
 * under the terms of the GNU General Public License, either version 2 of
 * the License, or (at your option) any later version. See COPYING.
 */

#include "config.h"

#include <assert.h>
#include "fixme.h"
#include <stdio.h>
#include <string.h>

#include "glue-main.h"
#include "glue-shm.h"

#include "keyboard.h"

#define COMP "keyboard"

struct cpssp {
      /* Ports */
      struct sig_ps2 *port_ps2;
      struct sig_boolean *port_opt_num_led;
      struct sig_boolean *port_opt_caps_led;
      struct sig_boolean *port_opt_scroll_led;

      uint8_t buffer[8];
      unsigned int head;
      unsigned int tail;

      unsigned char keyboard_command;
      unsigned char led_status;

      unsigned long long delay;
      unsigned long long repeat;

      int repeated_key;
};

/* Keyboard replies */
#define KBD_REPLY_POR           0xAA /* Power on reset */
#define KBD_REPLY_ACK           0xFA /* Command ACK */
#define KBD_REPLY_RESEND        0xFE /* Command NACK, send the cmd again */

/* Keyboard commands */
/* see PC-Hardware 5th revision, pp. 1038 */
#define KBD_CMD_EX_ENABLE       0xEA /* Enable extra keys */
#define KBD_CMD_SET_LEDS        0xED /* Set keyboard leds */
#define KBD_CMD_ECHO            0xEE
#define KBD_CMD_SSCANSET        0xF0 /* Set scancode table */
#define KBD_CMD_GETID           0xF2 /* Get identity string */
#define KBD_CMD_SET_RATE        0xF3 /* Set typematic rate */
#define KBD_CMD_ENABLE          0xF4 /* Enable scanning */
#define KBD_CMD_DISABLE         0xF5 /* Disable scanning */
#define KBD_CMD_STD_ENABLE      0xF6 /* Set standard settings and enable */
#define KBD_CMD_SETALL_MB       0xF8 /* Disable autorepeat? */
#define KBD_CMD_RESET           0xFF /* Reset */

/* mapping: key number to key code */
static const char kc_mapping[128][6] = {
      { 0x00 },
      { 0x01 },
      { 0x02 },
      { 0x03 },
      { 0x04 },
      { 0x05 },
      { 0x06 },
      { 0x07 },
      { 0x08 },
      { 0x09 },
      { 0x0a },
      { 0x0b },
      { 0x0c },
      { 0x0d },
      { 0x0e },
      { 0x0f },
      { 0x10 },
      { 0x11 },
      { 0x12 },
      { 0x13 },
      { 0x14 },
      { 0x15 },
      { 0x16 },
      { 0x17 },
      { 0x18 },
      { 0x19 },
      { 0x1a },
      { 0x1b },
      { 0x1c },
      { 0x1d },
      { 0x1e },
      { 0x1f },
      { 0x20 },
      { 0x21 },
      { 0x22 },
      { 0x23 },
      { 0x24 },
      { 0x25 },
      { 0x26 },
      { 0x27 },
      { 0x28 },
      { 0x29 },
      { 0x2a },
      { 0x2b },
      { 0x2c },
      { 0x2d },
      { 0x2e },
      { 0x2f },
      { 0x30 },
      { 0x31 },
      { 0x32 },
      { 0x33 },
      { 0x34 },
      { 0x35 },
      { 0x36 },
      { 0x37 },
      { 0x38 },
      { 0x39 },
      { 0x3a },
      { 0x3b },
      { 0x3c },
      { 0x3d },
      { 0x3e },
      { 0x3f },
      { 0x40 },
      { 0x41 },
      { 0x42 },
      { 0x43 },
      { 0x44 },
      { 0x45 },
      { 0x46 },
      { 0x47 },
      { 0x48 },
      { 0x49 },
      { 0x4a },
      { 0x4b },
      { 0x4c },
      { 0x4d },
      { 0x4e },
      { 0x4f },
      { 0x50 },
      { 0x51 },
      { 0x52 },
      { 0x53 },

      { 0x54 },   /* FIXME 84 */
      { 0x55 },   /* FIXME 85 */
      { 0x56 },   /* FIXME 86 */

      { 0x57 },
      { 0x58 },

      { 0x00 },   /* FIXME 89 */
      { 0x00 },   /* FIXME 90 */
      { 0x00 },   /* FIXME 91 */
      { 0x00 },   /* FIXME 92 */
      { 0x00 },   /* FIXME 93 */
      { 0x00 },   /* FIXME 94 */
      { 0x00 },   /* FIXME 95 */

      { 0xe0, 0x1c },
      { 0xe0, 0x1d },
      { 0xe0, 0x35 },
      { 0xe0, 0x2a, 0xe0, 0x37 },
      { 0xe0, 0x38 },

      { 0x00 },   /* FIXME 101 */

      { 0xe0, 0x2a, 0xe0, 0x47 },
      { 0xe0, 0x2a, 0xe0, 0x48 },
      { 0xe0, 0x2a, 0xe0, 0x49 },
      { 0xe0, 0x2a, 0xe0, 0x4b },
      { 0xe0, 0x2a, 0xe0, 0x4d },
      { 0xe0, 0x2a, 0xe0, 0x4f },
      { 0xe0, 0x2a, 0xe0, 0x50 },
      { 0xe0, 0x2a, 0xe0, 0x51 },
      { 0xe0, 0x2a, 0xe0, 0x52 },
      { 0xe0, 0x2a, 0xe0, 0x53 },

      { 0x00 },   /* FIXME 112 */
      { 0x00 },   /* FIXME 113 */
      { 0x00 },   /* FIXME 114 */
      { 0x00 },   /* FIXME 115 */
      { 0x00 },   /* FIXME 116 */
      { 0x00 },   /* FIXME 117 */
      { 0x00 },   /* FIXME 118 */

      { 0xe1, 0x1d, 0x45, 0xe1, 0x9d, 0xc5 },

      { 0x00 },   /* FIXME 120 */
      { 0x00 },   /* FIXME 121 */
      { 0x00 },   /* FIXME 122 */
      { 0x00 },   /* FIXME 123 */
      { 0x00 },   /* FIXME 124 */

      { 0xe0, 0x5b },
      { 0xe0, 0x5c },
      { 0xe0, 0x5d }
};

static void
kbd_reply(struct cpssp *cpssp, unsigned char byte)
{
      sig_ps2_send(cpssp->port_ps2, cpssp, byte);
}

static void
_kbd_command(struct cpssp *cpssp, uint8_t value)
{
      /*
       * See PC Hardware (5. Auflage).
       */
      if (cpssp->keyboard_command == 0) {
            switch (value) {
            case 0x00:  /* ? */
                  kbd_reply(cpssp, KBD_REPLY_ACK);
                  break;

            case 0x05:  /* ? */
                  kbd_reply(cpssp, KBD_REPLY_RESEND);
                  break;

            case KBD_CMD_EX_ENABLE: /* 0xea */
                  kbd_reply(cpssp, KBD_REPLY_ACK);
                  cpssp->keyboard_command = value;
                  break;

            case KBD_CMD_SET_LEDS: /* 0xed */
                  kbd_reply(cpssp, KBD_REPLY_ACK);
                  cpssp->keyboard_command = value;
                  break;

            case KBD_CMD_ECHO: /* 0xee */
                  kbd_reply(cpssp, KBD_CMD_ECHO);
                  break;

            case KBD_CMD_SSCANSET: /* 0xf0 */
                  kbd_reply(cpssp, KBD_REPLY_ACK);
                  cpssp->keyboard_command = value;
                  break;

            case KBD_CMD_GETID: /* 0xf2 */
                  kbd_reply(cpssp, KBD_REPLY_ACK);
                  if (0) {
                        /* AT keyboard */
                  } else {
                        /* MF-II keyboard */
                        kbd_reply(cpssp, 0xab);
                        kbd_reply(cpssp, 0x83);
                  }
                  break;

            case KBD_CMD_SET_RATE: /* 0xf3 */
                  kbd_reply(cpssp, KBD_REPLY_ACK);
                  cpssp->keyboard_command = value;
                  break;

            case KBD_CMD_ENABLE: /* 0xf4 */
                  kbd_reply(cpssp, KBD_REPLY_ACK);
                  break;

            case KBD_CMD_DISABLE: /* 0xf5 */
                  kbd_reply(cpssp, KBD_REPLY_ACK);
                  break;

            case KBD_CMD_STD_ENABLE: /* 0xf6 */
                  kbd_reply(cpssp, KBD_REPLY_ACK);
                  break;

            case KBD_CMD_SETALL_MB: /* 0xf8 */
                  kbd_reply(cpssp, KBD_REPLY_ACK);
                  break;

            case KBD_CMD_RESET: /* 0xff */
                  /*
                   * Now reset the keyboard, which will take a while.
                   * When we are done, put KBD_REPLY_POR into buffer,
                   * since driver is waiting for this.
                   */
                  cpssp->delay = (TIME_HZ * 500) / 1000;
                  cpssp->repeat = (TIME_HZ * 91) / 1000;

                  kbd_reply(cpssp, KBD_REPLY_ACK);
                  kbd_reply(cpssp, KBD_REPLY_POR);
                  break;

            default:
                  fprintf(stderr, "WARNING: keyboard: got command 0x%02x\n",
                              value);
                  kbd_reply(cpssp, KBD_REPLY_ACK);
                  break;
            }

      } else {
            switch (cpssp->keyboard_command) {
            case KBD_CMD_EX_ENABLE: /* 0xea */
                  kbd_reply(cpssp, KBD_REPLY_ACK);
                  /* ... - FIXME VOSSI */
                  break;

            case KBD_CMD_SET_LEDS: /* 0xed */
                  kbd_reply(cpssp, KBD_REPLY_ACK);
                  cpssp->led_status = value;
                  sig_boolean_set(cpssp->port_opt_scroll_led, cpssp,
                              value & 0x01);
                  sig_boolean_set(cpssp->port_opt_num_led, cpssp,
                              (value & 0x02) == 0x02);
                  sig_boolean_set(cpssp->port_opt_caps_led, cpssp,
                              (value & 0x04) == 0x04);
                  break;

            case KBD_CMD_SSCANSET: /* 0xf0 */
                  kbd_reply(cpssp, KBD_REPLY_ACK);
                  switch (value) {
                  case 0: /* read current setting */
                        kbd_reply(cpssp, 2);    /* FIXME VOSSI */
                        break;

                  case 1:
                  case 2:
                  case 3: /* set scancode table */
                        /* ... - FIXME VOSSI */
                        break;

                  default: /* bad parameter */
                        /* what should we do here? - FIXME VOSSI */
                        break;
                  }
                  break;

            case KBD_CMD_SET_RATE: /* 0xf3 */
                  /* set repeat rate */
                  kbd_reply(cpssp, KBD_REPLY_ACK);
                  /* calculate delay and repeat rates */
                  cpssp->delay = (TIME_HZ * 250 * (((value >> 5) & 0x03) + 1))
                              / 1000;
                  cpssp->repeat = ((1 << ((value >> 3) & 0x03))
                              * ((value & 0x07) + 8) * TIME_HZ) / 240;
                  break;

            default:
                  assert(0);
            }

            cpssp->keyboard_command = 0;
      }
}

static void
kbd_recv2(void *_cpssp)
{
      struct cpssp *cpssp = (struct cpssp *) _cpssp;
      uint8_t byte;

      byte = cpssp->buffer[cpssp->tail];
      cpssp->tail = (cpssp->tail + 1) % sizeof(cpssp->buffer);

      _kbd_command(cpssp, byte);

      if (cpssp->tail != cpssp->head) {
            /* Sending/receiving a byte using 9600 Baud takes about 1ms. */
            time_call_after(TIME_HZ / 1000, kbd_recv2, cpssp);
      }
}

static void
kbd_recv(void *_cpssp, uint8_t byte)
{
      struct cpssp *cpssp = (struct cpssp *) _cpssp;

      cpssp->buffer[cpssp->head] = byte;
      cpssp->head = (cpssp->head + 1) % sizeof(cpssp->buffer);
      
      /* Sending/receiving a byte using 9600 Baud takes about 1msec. */
      time_call_after(TIME_HZ / 1000, kbd_recv2, cpssp);
}

static void
keyboard_repeat(void * _cpssp)
{
      struct cpssp *cpssp = (struct cpssp *) _cpssp;
      int len;
      unsigned char key_code[6];
      int i;

      for (len = 0; len < 6 && kc_mapping[cpssp->repeated_key][len] != 0x00; len++) {
            key_code[len] = kc_mapping[cpssp->repeated_key][len];
      }

      for (i = 0; i < len; i++) {
            kbd_reply(cpssp, key_code[i]);
      }

      time_call_after(cpssp->repeat, keyboard_repeat, cpssp);
}

static int
keyboard_is_repeated(int key)
{
      return     (key != 0x2a) /* left shift */
            && (key != 0x36) /* right shift */
            && (key != 0x3a) /* caps lock */
            && (key != 0x1d) /* left ctrl */
            && (key != 0x61) /* right ctrl */
            && (key != 0x38) /* left alt */
            && (key != 0x64) /* right alt */
            && (key != 0x45) /* num lock */
            && (key != 0x46) /* scroll lock (?) */
            && (key != 0x7d) /* left Windows-key */
            && (key != 0x7e) /* right Windows-key */
            && (key != 0x77) /* pause */
            ;
}

static void
keyboard_event(void *_cpssp, int key, int press)
{
      struct cpssp *cpssp = (struct cpssp *) _cpssp;
      int len;
      unsigned char key_code[6];
      int i;

      assert(key < 128);

      if (! kc_mapping[key][0]) {
            fprintf(stderr, "ignoring request for unknown key %d\n", key);
            return;
      }

      if (keyboard_is_repeated(key)) {
            time_call_delete(keyboard_repeat, cpssp);
      }

      for (len = 0; len < 6 && kc_mapping[key][len] != 0x00; len++) {
            key_code[len] = kc_mapping[key][len];
      }
      if (! press) {
            switch (len) {
            case 1:
                  key_code[0] |= 0x80;
                  break;
            case 2:
                  assert(key_code[0] == 0xe0);
                  key_code[1] |= 0x80;
                  break;
            case 4:
                  assert(key_code[0] == 0xe0);
                  key_code[1] = kc_mapping[key][3] | 0x80;
                  assert(key_code[2] == 0xe0);
                  key_code[3] = kc_mapping[key][1] | 0x80;
                  break;
            default:
                  fprintf(stderr, "release unreleasable key %d\n", key);
                  return;
            }
      }
      for (i = 0; i < len; i++) {
            kbd_reply(cpssp, key_code[i]);
      }

      if (press && keyboard_is_repeated(key)) {
            cpssp->repeated_key = key;
            time_call_after(cpssp->delay, keyboard_repeat, cpssp);
      }
}

#define func(nr) \
static void \
keyboard_key ## nr ## _set(void *_cpssp, unsigned int val) \
{ \
      struct cpssp *cpssp = (struct cpssp *) _cpssp; \
      \
      keyboard_event(cpssp, nr, val); \
}

func(0) func(1) func(2) func(3)
func(4) func(5) func(6) func(7)
func(8) func(9) func(10) func(11)
func(12) func(13) func(14) func(15)
func(16) func(17) func(18) func(19)
func(20) func(21) func(22) func(23)
func(24) func(25) func(26) func(27)
func(28) func(29) func(30) func(31)
func(32) func(33) func(34) func(35)
func(36) func(37) func(38) func(39)
func(40) func(41) func(42) func(43)
func(44) func(45) func(46) func(47)
func(48) func(49) func(50) func(51)
func(52) func(53) func(54) func(55)
func(56) func(57) func(58) func(59)
func(60) func(61) func(62) func(63)
func(64) func(65) func(66) func(67)
func(68) func(69) func(70) func(71)
func(72) func(73) func(74) func(75)
func(76) func(77) func(78) func(79)
func(80) func(81) func(82) func(83)
func(84) func(85) func(86) func(87)
func(88) func(89) func(90) func(91)
func(92) func(93) func(94) func(95)
func(96) func(97) func(98) func(99)
func(100) func(101) func(102) func(103)
func(104) func(105) func(106) func(107)
func(108) func(109) func(110) func(111)
func(112) func(113) func(114) func(115)
func(116) func(117) func(118) func(119)
func(120) func(121) func(122) func(123)
func(124) func(125) func(126) func(127)

#undef func

void
keyboard_init(
      unsigned int nr,
      struct sig_ps2 *port_ps2,
      struct sig_boolean *port_key0,
      struct sig_boolean *port_key1,
      struct sig_boolean *port_key2,
      struct sig_boolean *port_key3,
      struct sig_boolean *port_key4,
      struct sig_boolean *port_key5,
      struct sig_boolean *port_key6,
      struct sig_boolean *port_key7,
      struct sig_boolean *port_key8,
      struct sig_boolean *port_key9,
      struct sig_boolean *port_key10,
      struct sig_boolean *port_key11,
      struct sig_boolean *port_key12,
      struct sig_boolean *port_key13,
      struct sig_boolean *port_key14,
      struct sig_boolean *port_key15,
      struct sig_boolean *port_key16,
      struct sig_boolean *port_key17,
      struct sig_boolean *port_key18,
      struct sig_boolean *port_key19,
      struct sig_boolean *port_key20,
      struct sig_boolean *port_key21,
      struct sig_boolean *port_key22,
      struct sig_boolean *port_key23,
      struct sig_boolean *port_key24,
      struct sig_boolean *port_key25,
      struct sig_boolean *port_key26,
      struct sig_boolean *port_key27,
      struct sig_boolean *port_key28,
      struct sig_boolean *port_key29,
      struct sig_boolean *port_key30,
      struct sig_boolean *port_key31,
      struct sig_boolean *port_key32,
      struct sig_boolean *port_key33,
      struct sig_boolean *port_key34,
      struct sig_boolean *port_key35,
      struct sig_boolean *port_key36,
      struct sig_boolean *port_key37,
      struct sig_boolean *port_key38,
      struct sig_boolean *port_key39,
      struct sig_boolean *port_key40,
      struct sig_boolean *port_key41,
      struct sig_boolean *port_key42,
      struct sig_boolean *port_key43,
      struct sig_boolean *port_key44,
      struct sig_boolean *port_key45,
      struct sig_boolean *port_key46,
      struct sig_boolean *port_key47,
      struct sig_boolean *port_key48,
      struct sig_boolean *port_key49,
      struct sig_boolean *port_key50,
      struct sig_boolean *port_key51,
      struct sig_boolean *port_key52,
      struct sig_boolean *port_key53,
      struct sig_boolean *port_key54,
      struct sig_boolean *port_key55,
      struct sig_boolean *port_key56,
      struct sig_boolean *port_key57,
      struct sig_boolean *port_key58,
      struct sig_boolean *port_key59,
      struct sig_boolean *port_key60,
      struct sig_boolean *port_key61,
      struct sig_boolean *port_key62,
      struct sig_boolean *port_key63,
      struct sig_boolean *port_key64,
      struct sig_boolean *port_key65,
      struct sig_boolean *port_key66,
      struct sig_boolean *port_key67,
      struct sig_boolean *port_key68,
      struct sig_boolean *port_key69,
      struct sig_boolean *port_key70,
      struct sig_boolean *port_key71,
      struct sig_boolean *port_key72,
      struct sig_boolean *port_key73,
      struct sig_boolean *port_key74,
      struct sig_boolean *port_key75,
      struct sig_boolean *port_key76,
      struct sig_boolean *port_key77,
      struct sig_boolean *port_key78,
      struct sig_boolean *port_key79,
      struct sig_boolean *port_key80,
      struct sig_boolean *port_key81,
      struct sig_boolean *port_key82,
      struct sig_boolean *port_key83,
      struct sig_boolean *port_key84,
      struct sig_boolean *port_key85,
      struct sig_boolean *port_key86,
      struct sig_boolean *port_key87,
      struct sig_boolean *port_key88,
      struct sig_boolean *port_key89,
      struct sig_boolean *port_key90,
      struct sig_boolean *port_key91,
      struct sig_boolean *port_key92,
      struct sig_boolean *port_key93,
      struct sig_boolean *port_key94,
      struct sig_boolean *port_key95,
      struct sig_boolean *port_key96,
      struct sig_boolean *port_key97,
      struct sig_boolean *port_key98,
      struct sig_boolean *port_key99,
      struct sig_boolean *port_key100,
      struct sig_boolean *port_key101,
      struct sig_boolean *port_key102,
      struct sig_boolean *port_key103,
      struct sig_boolean *port_key104,
      struct sig_boolean *port_key105,
      struct sig_boolean *port_key106,
      struct sig_boolean *port_key107,
      struct sig_boolean *port_key108,
      struct sig_boolean *port_key109,
      struct sig_boolean *port_key110,
      struct sig_boolean *port_key111,
      struct sig_boolean *port_key112,
      struct sig_boolean *port_key113,
      struct sig_boolean *port_key114,
      struct sig_boolean *port_key115,
      struct sig_boolean *port_key116,
      struct sig_boolean *port_key117,
      struct sig_boolean *port_key118,
      struct sig_boolean *port_key119,
      struct sig_boolean *port_key120,
      struct sig_boolean *port_key121,
      struct sig_boolean *port_key122,
      struct sig_boolean *port_key123,
      struct sig_boolean *port_key124,
      struct sig_boolean *port_key125,
      struct sig_boolean *port_key126,
      struct sig_boolean *port_key127,
      struct sig_boolean *port_opt_num_led,
      struct sig_boolean *port_opt_caps_led,
      struct sig_boolean *port_opt_scroll_led
)
{
      static const struct sig_ps2_funcs funcs = {
            .recv = kbd_recv,
      };

#define func(nr) \
      static const struct sig_boolean_funcs key ## nr ## _funcs = { \
            .set = keyboard_key ## nr ## _set, \
      }
      func(0); func(1); func(2); func(3);
      func(4); func(5); func(6); func(7);
      func(8); func(9); func(10); func(11);
      func(12); func(13); func(14); func(15);
      func(16); func(17); func(18); func(19);
      func(20); func(21); func(22); func(23);
      func(24); func(25); func(26); func(27);
      func(28); func(29); func(30); func(31);
      func(32); func(33); func(34); func(35);
      func(36); func(37); func(38); func(39);
      func(40); func(41); func(42); func(43);
      func(44); func(45); func(46); func(47);
      func(48); func(49); func(50); func(51);
      func(52); func(53); func(54); func(55);
      func(56); func(57); func(58); func(59);
      func(60); func(61); func(62); func(63);
      func(64); func(65); func(66); func(67);
      func(68); func(69); func(70); func(71);
      func(72); func(73); func(74); func(75);
      func(76); func(77); func(78); func(79);
      func(80); func(81); func(82); func(83);
      func(84); func(85); func(86); func(87);
      func(88); func(89); func(90); func(91);
      func(92); func(93); func(94); func(95);
      func(96); func(97); func(98); func(99);
      func(100); func(101); func(102); func(103);
      func(104); func(105); func(106); func(107);
      func(108); func(109); func(110); func(111);
      func(112); func(113); func(114); func(115);
      func(116); func(117); func(118); func(119);
      func(120); func(121); func(122); func(123);
      func(124); func(125); func(126); func(127);

#undef func

      struct cpssp *cpssp;

      cpssp = shm_map(COMP, nr, sizeof(*cpssp), 0);

      cpssp->head = 0;
      cpssp->tail = 0;

      cpssp->delay = (TIME_HZ * 500) / 1000;
      cpssp->repeat = (TIME_HZ * 91) / 1000;

      /* Call */
      cpssp->port_ps2 = port_ps2;
      sig_ps2_connect(port_ps2, cpssp, &funcs);

      /* In */
#define func(nr) \
      sig_boolean_connect_in(port_key ## nr, cpssp, &key ## nr ## _funcs)

      func(0); func(1); func(2); func(3);
      func(4); func(5); func(6); func(7);
      func(8); func(9); func(10); func(11);
      func(12); func(13); func(14); func(15);
      func(16); func(17); func(18); func(19);
      func(20); func(21); func(22); func(23);
      func(24); func(25); func(26); func(27);
      func(28); func(29); func(30); func(31);
      func(32); func(33); func(34); func(35);
      func(36); func(37); func(38); func(39);
      func(40); func(41); func(42); func(43);
      func(44); func(45); func(46); func(47);
      func(48); func(49); func(50); func(51);
      func(52); func(53); func(54); func(55);
      func(56); func(57); func(58); func(59);
      func(60); func(61); func(62); func(63);
      func(64); func(65); func(66); func(67);
      func(68); func(69); func(70); func(71);
      func(72); func(73); func(74); func(75);
      func(76); func(77); func(78); func(79);
      func(80); func(81); func(82); func(83);
      func(84); func(85); func(86); func(87);
      func(88); func(89); func(90); func(91);
      func(92); func(93); func(94); func(95);
      func(96); func(97); func(98); func(99);
      func(100); func(101); func(102); func(103);
      func(104); func(105); func(106); func(107);
      func(108); func(109); func(110); func(111);
      func(112); func(113); func(114); func(115);
      func(116); func(117); func(118); func(119);
      func(120); func(121); func(122); func(123);
      func(124); func(125); func(126); func(127);

#undef func

      /* Out */
      cpssp->port_opt_num_led = port_opt_num_led;
      cpssp->port_opt_caps_led = port_opt_caps_led;
      cpssp->port_opt_scroll_led = port_opt_scroll_led;
}

void
keyboard_create(unsigned int nr, const char *name)
{
      struct cpssp *cpssp;

      shm_create(COMP, nr, sizeof(*cpssp));
      cpssp = shm_map(COMP, nr, sizeof(*cpssp), 0);

      shm_unmap(cpssp, sizeof(*cpssp));
}

void
keyboard_destroy(unsigned int nr)
{
      struct cpssp *cpssp;

      cpssp = shm_map(COMP, nr, sizeof(*cpssp), 0);

      shm_unmap(cpssp, sizeof(*cpssp));
      shm_destroy(COMP, nr);
}

Generated by  Doxygen 1.6.0   Back to index