Search
lxdream.org :: lxdream/src/maple/kbd.c
lxdream 0.9.1
released Jun 29
Download Now
filename src/maple/kbd.c
changeset 1072:d82e04e6d497
prev1034:7044e01148f0
next1224:7762a347ca33
author nkeynes
date Fri Sep 10 08:48:34 2010 +1000 (13 years ago)
permissions -rw-r--r--
last change Run the eventq at the end of the time-slice rather than the beginning, so
that it runs for the correct period of time when the time-slice finishes
early
file annotate diff log raw
nkeynes@608
     1
/**
nkeynes@611
     2
 * $Id$
nkeynes@608
     3
 *
nkeynes@608
     4
 * Implements the standard dreamcast keyboard
nkeynes@848
     5
 * Part No. HKT-7620
nkeynes@608
     6
 *
nkeynes@608
     7
 * Copyright (c) 2005 Nathan Keynes.
nkeynes@608
     8
 *
nkeynes@608
     9
 * This program is free software; you can redistribute it and/or modify
nkeynes@608
    10
 * it under the terms of the GNU General Public License as published by
nkeynes@608
    11
 * the Free Software Foundation; either version 2 of the License, or
nkeynes@608
    12
 * (at your option) any later version.
nkeynes@608
    13
 *
nkeynes@608
    14
 * This program is distributed in the hope that it will be useful,
nkeynes@608
    15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
nkeynes@608
    16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
nkeynes@608
    17
 * GNU General Public License for more details.
nkeynes@608
    18
 */
nkeynes@608
    19
nkeynes@608
    20
#include <stdlib.h>
nkeynes@608
    21
#include <X11/keysym.h>
nkeynes@608
    22
#include "dream.h"
nkeynes@608
    23
#include "dreamcast.h"
nkeynes@608
    24
#include "display.h"
nkeynes@608
    25
#include "maple.h"
nkeynes@608
    26
nkeynes@608
    27
#define KEYBOARD_IDENT {  0x00, 0x00, 0x00, 0x40,  0x02, 0x05, 0x00, 0x80,  0x00, 0x00, 0x00, 0x00, \
nkeynes@736
    28
    0x00, 0x00, 0x00, 0x00,  0x01, 0x00, 0x4b, 0x65,  0x79, 0x62, 0x6f, 0x61,  0x72, 0x64, 0x20, 0x20, \
nkeynes@736
    29
    0x20, 0x20, 0x20, 0x20,  0x20, 0x20, 0x20, 0x20,  0x20, 0x20, 0x20, 0x20,  0x20, 0x20, 0x20, 0x20, \
nkeynes@736
    30
    0x20, 0x20, 0x20, 0x20,  0x50, 0x72, 0x6f, 0x64,  0x75, 0x63, 0x65, 0x64,  0x20, 0x42, 0x79, 0x20, \
nkeynes@736
    31
    0x6f, 0x72, 0x20, 0x55,  0x6e, 0x64, 0x65, 0x72,  0x20, 0x4c, 0x69, 0x63,  0x65, 0x6e, 0x73, 0x65, \
nkeynes@736
    32
    0x20, 0x46, 0x72, 0x6f,  0x6d, 0x20, 0x53, 0x45,  0x47, 0x41, 0x20, 0x45,  0x4e, 0x54, 0x45, 0x52, \
nkeynes@736
    33
    0x50, 0x52, 0x49, 0x53,  0x45, 0x53, 0x2c, 0x4c,  0x54, 0x44, 0x2e, 0x20,  0x20, 0x20, 0x20, 0x20, \
nkeynes@736
    34
    0x2c, 0x01, 0x90, 0x01 }
nkeynes@608
    35
nkeynes@608
    36
#define KEYBOARD_VERSION {0x56, 0x65, 0x72, 0x73,  0x69, 0x6f, 0x6e, 0x20,  0x31, 0x2e, 0x30, 0x31, \
nkeynes@736
    37
    0x30, 0x2c, 0x31, 0x39,  0x39, 0x39, 0x2f, 0x30,  0x34, 0x2f, 0x32, 0x37,  0x2c, 0x33, 0x31, 0x35, \
nkeynes@736
    38
    0x2d, 0x36, 0x32, 0x31,  0x31, 0x2d, 0x41, 0x4d,  0x20, 0x20, 0x20, 0x2c,  0x4b, 0x65, 0x79, 0x20, \
nkeynes@736
    39
    0x53, 0x63, 0x61, 0x6e,  0x20, 0x4d, 0x6f, 0x64,  0x75, 0x6c, 0x65, 0x20,  0x3a, 0x20, 0x54, 0x68, \
nkeynes@736
    40
    0x65, 0x20, 0x32, 0x6e,  0x64, 0x20, 0x45, 0x64,  0x69, 0x74, 0x69, 0x6f,  0x6e, 0x2e, 0x20, 0x30, \
nkeynes@736
    41
    0x34, 0x2f, 0x32, 0x35 }
nkeynes@608
    42
nkeynes@608
    43
void keyboard_attach( maple_device_t dev );
nkeynes@608
    44
void keyboard_detach( maple_device_t dev );
nkeynes@608
    45
maple_device_t keyboard_clone( maple_device_t dev );
nkeynes@608
    46
maple_device_t keyboard_new();
nkeynes@608
    47
int keyboard_get_cond( maple_device_t dev, int function, unsigned char *outbuf,
nkeynes@736
    48
                       unsigned int *outlen );
nkeynes@608
    49
nkeynes@608
    50
typedef struct keyboard_device {
nkeynes@608
    51
    struct maple_device dev;
nkeynes@608
    52
    uint8_t condition[8];
nkeynes@608
    53
} *keyboard_device_t; 
nkeynes@608
    54
nkeynes@1034
    55
struct maple_device_class keyboard_class = { "Sega Keyboard", MAPLE_GRAB_DONTCARE|MAPLE_TYPE_PRIMARY, keyboard_new };
nkeynes@608
    56
nkeynes@608
    57
static struct keyboard_device base_keyboard = {
nkeynes@1034
    58
        { MAPLE_DEVICE_TAG, &keyboard_class,
nkeynes@838
    59
                KEYBOARD_IDENT, KEYBOARD_VERSION, 
nkeynes@1072
    60
                NULL, keyboard_attach, keyboard_detach, maple_default_destroy,
nkeynes@1034
    61
                keyboard_clone, NULL, NULL, keyboard_get_cond, NULL, NULL, NULL,
nkeynes@1034
    62
                NULL, NULL, NULL},
nkeynes@736
    63
                {0,0,0,0,0,0,0,0}, 
nkeynes@608
    64
};
nkeynes@608
    65
nkeynes@608
    66
#define KEYBOARD(x) ((keyboard_device_t)(x))
nkeynes@608
    67
nkeynes@608
    68
maple_device_t keyboard_new( )
nkeynes@608
    69
{
nkeynes@608
    70
    keyboard_device_t dev = malloc( sizeof(struct keyboard_device) );
nkeynes@608
    71
    memcpy( dev, &base_keyboard, sizeof(base_keyboard) );
nkeynes@608
    72
    return MAPLE_DEVICE(dev);
nkeynes@608
    73
}
nkeynes@608
    74
nkeynes@608
    75
maple_device_t keyboard_clone( maple_device_t srcdevice )
nkeynes@608
    76
{
nkeynes@608
    77
    keyboard_device_t src = (keyboard_device_t)srcdevice;
nkeynes@608
    78
    keyboard_device_t dev = (keyboard_device_t)keyboard_new();
nkeynes@608
    79
    memcpy( dev->condition, src->condition, sizeof(src->condition) );
nkeynes@608
    80
    return MAPLE_DEVICE(dev);
nkeynes@608
    81
}
nkeynes@608
    82
nkeynes@608
    83
void keyboard_key_down( keyboard_device_t dev, uint8_t key )
nkeynes@608
    84
{
nkeynes@608
    85
    int i;
nkeynes@608
    86
    for( i=2; i<8; i++ ) {
nkeynes@736
    87
        if( dev->condition[i] == key ) {
nkeynes@736
    88
            return; // key already down, missed event or repeat
nkeynes@736
    89
        } else if( dev->condition[i] == 0 ) {
nkeynes@736
    90
            dev->condition[i] = key;
nkeynes@736
    91
            return;
nkeynes@736
    92
        }
nkeynes@608
    93
    }
nkeynes@608
    94
    /* Key array is full - skip for the moment */
nkeynes@608
    95
}
nkeynes@608
    96
nkeynes@608
    97
void keyboard_key_up( keyboard_device_t dev, uint8_t key )
nkeynes@608
    98
{
nkeynes@608
    99
    int i;
nkeynes@608
   100
    for( i=2; i<8; i++ ) {
nkeynes@736
   101
        if( dev->condition[i] == key ) {
nkeynes@736
   102
            for( ; i<7; i++ ) {
nkeynes@736
   103
                dev->condition[i] = dev->condition[i+1];
nkeynes@736
   104
            }
nkeynes@736
   105
            dev->condition[7] = 0;
nkeynes@736
   106
            break;
nkeynes@736
   107
        }
nkeynes@608
   108
    }
nkeynes@608
   109
}
nkeynes@608
   110
nkeynes@614
   111
void keyboard_input_hook( void *mdev, uint32_t keycode, uint32_t pressure, gboolean isKeyDown )
nkeynes@608
   112
{
nkeynes@608
   113
    keyboard_device_t dev = (keyboard_device_t)mdev;
nkeynes@608
   114
    uint16_t key = input_keycode_to_dckeysym( keycode );
nkeynes@608
   115
    if( key != 0 ) {
nkeynes@736
   116
        if( key >> 8 == 0xFF ) { // shift 
nkeynes@736
   117
            if( isKeyDown ) {
nkeynes@736
   118
                dev->condition[0] |= (key&0xFF);
nkeynes@736
   119
            } else {
nkeynes@736
   120
                dev->condition[0] &= ~(key&0xFF);
nkeynes@736
   121
            }
nkeynes@736
   122
        } else {
nkeynes@736
   123
            if( isKeyDown ) {
nkeynes@736
   124
                keyboard_key_down( dev, (uint8_t)key );
nkeynes@736
   125
            } else {
nkeynes@736
   126
                keyboard_key_up( dev, (uint8_t)key );
nkeynes@736
   127
            }
nkeynes@736
   128
        }
nkeynes@608
   129
    }
nkeynes@608
   130
    /*
nkeynes@608
   131
    fprintf( stderr, "Key cond: %02X %02X  %02X %02X %02X %02X %02X %02X\n",
nkeynes@608
   132
	     dev->condition[0], dev->condition[1], dev->condition[2],
nkeynes@608
   133
	     dev->condition[3], dev->condition[4], dev->condition[5],
nkeynes@608
   134
	     dev->condition[6], dev->condition[7] );
nkeynes@736
   135
     */     
nkeynes@608
   136
}
nkeynes@608
   137
nkeynes@608
   138
/**
nkeynes@608
   139
 * Device is being attached to the bus. Go through the config and reserve the
nkeynes@608
   140
 * keys we need.
nkeynes@608
   141
 */
nkeynes@608
   142
void keyboard_attach( maple_device_t mdev )
nkeynes@608
   143
{
nkeynes@849
   144
    input_register_keyboard_hook( keyboard_input_hook, mdev );
nkeynes@608
   145
}
nkeynes@608
   146
nkeynes@608
   147
void keyboard_detach( maple_device_t mdev )
nkeynes@608
   148
{
nkeynes@849
   149
    input_unregister_keyboard_hook( keyboard_input_hook, mdev );
nkeynes@608
   150
}
nkeynes@608
   151
nkeynes@608
   152
nkeynes@608
   153
int keyboard_get_cond( maple_device_t mdev, int function, unsigned char *outbuf,
nkeynes@736
   154
                       unsigned int *outlen )
nkeynes@608
   155
{
nkeynes@608
   156
    keyboard_device_t dev = (keyboard_device_t)mdev;
nkeynes@608
   157
    if( function == MAPLE_FUNC_KEYBOARD ) {
nkeynes@608
   158
        *outlen = 2;
nkeynes@608
   159
        memcpy( outbuf, dev->condition, 8 );
nkeynes@608
   160
        return 0;
nkeynes@608
   161
    } else {
nkeynes@608
   162
        return MAPLE_ERR_FUNC_UNSUP;
nkeynes@608
   163
    }
nkeynes@608
   164
}
nkeynes@608
   165
.