nkeynes@144: /** nkeynes@477: * $Id: display.c,v 1.12 2007-10-31 09:10: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@431: #include "pvr2/pvr2.h" nkeynes@144: nkeynes@531: display_driver_t display_driver_list[] = { nkeynes@531: &display_gtk_driver, nkeynes@531: &display_null_driver, nkeynes@531: NULL }; nkeynes@531: 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@451: { GL_UNSIGNED_BYTE, GL_BGRA, GL_RGBA8, 4 }, /* YUV decoded to ARGB8888 */ nkeynes@327: { GL_UNSIGNED_BYTE, GL_BGR, GL_RGB, 3 }, nkeynes@451: { GL_UNSIGNED_BYTE, GL_BGRA, GL_RGBA8, 4 }, nkeynes@477: { GL_UNSIGNED_BYTE, GL_BGRA, GL_RGBA8, 4 }, /* Index4 decoded */ nkeynes@477: { GL_UNSIGNED_BYTE, GL_BGRA, GL_RGBA8, 4 }, /* Index8 decoded */ nkeynes@477: { GL_UNSIGNED_BYTE, GL_BGRA, GL_RGBA8, 4 }, nkeynes@477: { GL_UNSIGNED_BYTE, GL_RGB, GL_RGB, 3 }, nkeynes@352: 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@451: static void input_delete_key( uint16_t keycode, input_key_callback_t callback, void *data, nkeynes@451: uint32_t value ) nkeynes@144: { nkeynes@144: struct keymap_entry *key = keymap[keycode]; nkeynes@451: if( key != NULL && key->callback == callback && key->data == data && key->value == value ) { 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@356: if( display_driver == NULL || keysym == NULL || display_driver->resolve_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@451: void input_unregister_key( const gchar *keysym, input_key_callback_t callback, nkeynes@451: void *data, uint32_t value ) 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@451: input_delete_key( keycode, callback, data, value ); 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@531: display_driver_t get_display_driver_by_name( const char *name ) nkeynes@531: { nkeynes@531: int i; nkeynes@531: if( name == NULL ) { nkeynes@531: return display_driver_list[0]; nkeynes@531: } nkeynes@531: for( i=0; display_driver_list[i] != NULL; i++ ) { nkeynes@531: if( strcasecmp( display_driver_list[i]->name, name ) == 0 ) { nkeynes@531: return display_driver_list[i]; nkeynes@531: } nkeynes@531: } nkeynes@531: nkeynes@531: return NULL; nkeynes@531: } nkeynes@144: nkeynes@144: nkeynes@370: gboolean display_set_driver( display_driver_t driver ) nkeynes@144: { nkeynes@370: gboolean rv = TRUE; nkeynes@370: 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@370: rv = driver->init_driver(); nkeynes@531: if( !rv ) { nkeynes@531: display_driver = NULL; nkeynes@370: } nkeynes@370: return rv; nkeynes@144: }