nkeynes@144: /** nkeynes@329: * $Id: display.c,v 1.5 2007-01-25 13:03:23 nkeynes Exp $ nkeynes@144: * nkeynes@144: * Generic support for keyboard and other input sources. The active display nkeynes@144: * driver is expected to deliver events here, where they're translated and nkeynes@144: * passed to the appropriate dreamcast controllers (if any). nkeynes@144: * nkeynes@144: * Copyright (c) 2005 Nathan Keynes. nkeynes@144: * nkeynes@144: * This program is free software; you can redistribute it and/or modify nkeynes@144: * it under the terms of the GNU General Public License as published by nkeynes@144: * the Free Software Foundation; either version 2 of the License, or nkeynes@144: * (at your option) any later version. nkeynes@144: * nkeynes@144: * This program is distributed in the hope that it will be useful, nkeynes@144: * but WITHOUT ANY WARRANTY; without even the implied warranty of nkeynes@144: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the nkeynes@144: * GNU General Public License for more details. nkeynes@144: */ nkeynes@144: nkeynes@144: #include nkeynes@144: #include nkeynes@144: #include "dream.h" nkeynes@144: #include "display.h" nkeynes@144: nkeynes@144: typedef struct keymap_entry { nkeynes@144: uint16_t keycode; nkeynes@144: input_key_callback_t callback; nkeynes@144: void *data; nkeynes@144: uint32_t value; nkeynes@144: } *keymap_entry_t; nkeynes@144: nkeynes@144: /** nkeynes@327: * Colour format information nkeynes@327: */ nkeynes@327: struct colour_format colour_formats[] = { nkeynes@329: { GL_UNSIGNED_SHORT_1_5_5_5_REV, GL_BGRA, GL_RGB5_A1, 2 }, nkeynes@327: { GL_UNSIGNED_SHORT_5_6_5, GL_RGB, GL_RGB5, 2 }, nkeynes@327: { GL_UNSIGNED_SHORT_4_4_4_4_REV, GL_BGRA, GL_RGBA4, 2 }, nkeynes@327: { GL_UNSIGNED_INT_8_8_8_8_REV, GL_BGRA, GL_RGBA8, 4 }, /* YUV decoded to ARGB8888 */ nkeynes@327: { GL_UNSIGNED_BYTE, GL_BGR, GL_RGB, 3 }, nkeynes@327: { GL_UNSIGNED_INT_8_8_8_8_REV, GL_BGRA, GL_RGBA8, 4 } nkeynes@327: }; nkeynes@327: nkeynes@327: /** nkeynes@144: * FIXME: make this more memory efficient nkeynes@144: */ nkeynes@144: struct keymap_entry *keymap[65536]; nkeynes@144: nkeynes@144: nkeynes@144: static struct keymap_entry *input_create_key( uint16_t keycode ) nkeynes@144: { nkeynes@144: struct keymap_entry *key = keymap[ keycode ]; nkeynes@144: if( key == NULL ) { nkeynes@144: key = malloc( sizeof( struct keymap_entry ) ); nkeynes@144: assert( key != NULL ); nkeynes@144: keymap[ keycode ] = key; nkeynes@144: key->keycode = keycode; nkeynes@144: } nkeynes@144: return key; nkeynes@144: } nkeynes@144: nkeynes@144: static void input_delete_key( uint16_t keycode ) nkeynes@144: { nkeynes@144: struct keymap_entry *key = keymap[keycode]; nkeynes@144: if( key != NULL ) { nkeynes@144: free( key ); nkeynes@144: keymap[keycode] = NULL; nkeynes@144: } nkeynes@144: } nkeynes@144: nkeynes@144: static struct keymap_entry *input_get_key( uint16_t keycode ) nkeynes@144: { nkeynes@144: return keymap[ keycode ]; nkeynes@144: } nkeynes@144: nkeynes@144: gboolean input_register_key( const gchar *keysym, input_key_callback_t callback, nkeynes@144: void *data, uint32_t value ) nkeynes@144: { nkeynes@271: int i; nkeynes@144: if( display_driver == NULL || keysym == NULL ) nkeynes@144: return FALSE; /* No display driver */ nkeynes@271: gchar **strv = g_strsplit(keysym, ",", 16); nkeynes@271: gchar **s = strv; nkeynes@271: while( *s != NULL ) { nkeynes@271: uint16_t keycode = display_driver->resolve_keysym(g_strstrip(*s)); nkeynes@271: if( keycode == 0 ) nkeynes@271: return FALSE; /* Invalid keysym */ nkeynes@271: nkeynes@271: struct keymap_entry *key = input_create_key( keycode ); nkeynes@271: key->callback = callback; nkeynes@271: key->data = data; nkeynes@271: key->value = value; nkeynes@271: s++; nkeynes@271: } nkeynes@271: g_strfreev(strv); nkeynes@144: return TRUE; nkeynes@144: } nkeynes@144: nkeynes@144: void input_unregister_key( const gchar *keysym ) nkeynes@144: { nkeynes@144: if( display_driver == NULL || keysym == NULL ) nkeynes@144: return; nkeynes@144: uint16_t keycode = display_driver->resolve_keysym(keysym); nkeynes@144: if( keycode == 0 ) nkeynes@144: return; nkeynes@144: input_delete_key( keycode ); nkeynes@144: } nkeynes@144: nkeynes@144: nkeynes@144: gboolean input_is_key_valid( const gchar *keysym ) nkeynes@144: { nkeynes@144: if( display_driver == NULL ) nkeynes@144: return FALSE; /* No display driver */ nkeynes@144: return display_driver->resolve_keysym(keysym) != 0; nkeynes@144: } nkeynes@144: nkeynes@144: gboolean input_is_key_registered( const gchar *keysym ) nkeynes@144: { nkeynes@144: if( display_driver == NULL ) nkeynes@144: return FALSE; nkeynes@144: uint16_t keycode = display_driver->resolve_keysym(keysym); nkeynes@144: if( keycode == 0 ) nkeynes@144: return FALSE; nkeynes@144: return input_get_key( keycode ) != NULL; nkeynes@144: } nkeynes@144: nkeynes@144: void input_event_keydown( uint16_t keycode ) nkeynes@144: { nkeynes@144: struct keymap_entry *key = input_get_key(keycode); nkeynes@144: if( key != NULL ) { nkeynes@144: key->callback( key->data, key->value, TRUE ); nkeynes@144: } nkeynes@144: } nkeynes@144: nkeynes@144: void input_event_keyup( uint16_t keycode ) nkeynes@144: { nkeynes@144: struct keymap_entry *key = input_get_key(keycode); nkeynes@144: if( key != NULL ) { nkeynes@144: key->callback( key->data, key->value, FALSE ); nkeynes@144: } nkeynes@144: } nkeynes@144: nkeynes@144: nkeynes@144: nkeynes@144: void display_set_driver( display_driver_t driver ) nkeynes@144: { nkeynes@144: if( display_driver != NULL && display_driver->shutdown_driver != NULL ) nkeynes@144: display_driver->shutdown_driver(); nkeynes@144: nkeynes@144: display_driver = driver; nkeynes@144: if( driver->init_driver != NULL ) nkeynes@144: driver->init_driver(); nkeynes@144: driver->set_display_format( 640, 480, COLFMT_ARGB8888 ); nkeynes@144: driver->set_render_format( 640, 480, COLFMT_ARGB8888, FALSE ); nkeynes@144: texcache_gl_init(); nkeynes@144: }