Search
lxdream.org :: lxdream/src/display.c
lxdream 0.9.1
released Jun 29
Download Now
filename src/display.c
changeset 608:4f588e52bce0
prev561:533f6b478071
next614:a2d239d4438a
author nkeynes
date Sat Jan 26 02:45:27 2008 +0000 (15 years ago)
permissions -rw-r--r--
last change Bug #50: Implement mouse and keyboard
view annotate diff log raw
     1 /**
     2  * $Id$
     3  *
     4  * Generic support for keyboard and other input sources. The active display
     5  * driver is expected to deliver events here, where they're translated and
     6  * passed to the appropriate dreamcast controllers (if any).
     7  *
     8  * Copyright (c) 2005 Nathan Keynes.
     9  *
    10  * This program is free software; you can redistribute it and/or modify
    11  * it under the terms of the GNU General Public License as published by
    12  * the Free Software Foundation; either version 2 of the License, or
    13  * (at your option) any later version.
    14  *
    15  * This program is distributed in the hope that it will be useful,
    16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    18  * GNU General Public License for more details.
    19  */
    21 #include <stdint.h>
    22 #include <assert.h>
    23 #include "dream.h"
    24 #include "display.h"
    25 #include "pvr2/pvr2.h"
    27 display_driver_t display_driver_list[] = { 
    28 #ifdef HAVE_GTK
    29 					   &display_gtk_driver,
    30 #endif
    31 					   &display_null_driver,
    32 					   NULL };
    34 typedef struct keymap_entry {
    35     uint16_t keycode;
    36     input_key_callback_t callback;
    37     void *data;
    38     uint32_t value;
    39     struct keymap_entry *next; // allow chaining
    40 } *keymap_entry_t;
    42 typedef struct mouse_entry {
    43     gboolean relative;
    44     input_mouse_callback_t callback;
    45     void *data;
    46     struct mouse_entry *next;
    47 } *mouse_entry_t;
    49 /**
    50  * Colour format information
    51  */
    52 struct colour_format colour_formats[] = {
    53     { GL_UNSIGNED_SHORT_1_5_5_5_REV, GL_BGRA, GL_RGB5_A1, 2 },
    54     { GL_UNSIGNED_SHORT_5_6_5, GL_RGB, GL_RGB5, 2 },
    55     { GL_UNSIGNED_SHORT_4_4_4_4_REV, GL_BGRA, GL_RGBA4, 2 },
    56     { GL_UNSIGNED_BYTE, GL_BGRA, GL_RGBA8, 4 }, /* YUV decoded to ARGB8888 */
    57     { GL_UNSIGNED_BYTE, GL_BGR, GL_RGB, 3 },
    58     { GL_UNSIGNED_BYTE, GL_BGRA, GL_RGBA8, 4 },
    59     { GL_UNSIGNED_BYTE, GL_BGRA, GL_RGBA8, 4 }, /* Index4 decoded */
    60     { GL_UNSIGNED_BYTE, GL_BGRA, GL_RGBA8, 4 }, /* Index8 decoded */
    61     { GL_UNSIGNED_BYTE, GL_BGRA, GL_RGBA8, 4 },
    62     { GL_UNSIGNED_BYTE, GL_RGB, GL_RGB, 3 },
    64 };
    66 /**
    67  * FIXME: make this more memory efficient
    68  */
    69 struct keymap_entry *keymap[65536];
    70 struct keymap_entry *keyhooks = NULL;
    71 struct mouse_entry *mousehooks = NULL;
    73 static struct keymap_entry *input_create_key( uint16_t keycode )
    74 {
    75     struct keymap_entry *key = keymap[ keycode ];
    76     if( key == NULL ) {
    77 	key = malloc( sizeof( struct keymap_entry ) );
    78 	assert( key != NULL );
    79 	keymap[ keycode ] = key;
    80 	key->keycode = keycode;
    81     }
    82     return key;
    83 }
    85 static void input_delete_key( uint16_t keycode, input_key_callback_t callback, void *data,
    86 			      uint32_t value )
    87 {
    88     struct keymap_entry *key = keymap[keycode];
    89     if( key != NULL && key->callback == callback && key->data == data && key->value == value ) {
    90 	free( key );
    91 	keymap[keycode] = NULL;
    92     }
    93 }
    95 static struct keymap_entry *input_get_key( uint16_t keycode )
    96 {
    97     return keymap[ keycode ];
    98 }
   100 gboolean input_register_key( const gchar *keysym, input_key_callback_t callback,
   101 			     void *data, uint32_t value )
   102 {
   103     if( display_driver == NULL || keysym == NULL || display_driver->resolve_keysym == NULL )
   104 	return FALSE; /* No display driver */
   105     gchar **strv = g_strsplit(keysym, ",", 16);
   106     gchar **s = strv;
   107     while( *s != NULL ) {
   108 	uint16_t keycode = display_driver->resolve_keysym(g_strstrip(*s));
   109 	if( keycode == 0 )
   110 	    return FALSE; /* Invalid keysym */
   112 	struct keymap_entry *key = input_create_key( keycode );
   113 	key->callback = callback;
   114 	key->data = data;
   115 	key->value = value;
   116 	s++;
   117     }
   118     g_strfreev(strv);
   119     return TRUE;
   120 }
   122 void input_unregister_key( const gchar *keysym, input_key_callback_t callback,
   123 			   void *data, uint32_t value )
   124 {
   125     if( display_driver == NULL || keysym == NULL || display_driver->resolve_keysym == NULL )
   126 	return;
   127     uint16_t keycode = display_driver->resolve_keysym(keysym);
   128     if( keycode == 0 )
   129 	return;
   130     input_delete_key( keycode, callback, data, value );
   131 }
   133 gboolean input_register_hook( input_key_callback_t callback,
   134 			      void *data )
   135 {
   136     keymap_entry_t key = malloc( sizeof( struct keymap_entry ) );
   137     assert( key != NULL );
   138     key->callback = callback;
   139     key->data = data;
   140     key->next = keyhooks;
   141     keyhooks = key;
   142     return TRUE;
   143 }
   145 void input_unregister_hook( input_key_callback_t callback,
   146 			    void *data )
   147 {
   148     keymap_entry_t key = keyhooks;
   149     if( key != NULL ) {
   150 	keymap_entry_t next = key->next;
   151 	if( key->callback == callback && key->data == data ) {
   152 	    free(key);
   153 	    keyhooks = next;
   154 	    return;
   155 	}
   156 	while( next != NULL ) {
   157 	    if( next->callback == callback && next->data == data ) {
   158 		key->next = next->next;
   159 		free(next);
   160 	    }
   161 	}
   162     }
   163 }
   165 gboolean input_register_mouse_hook( gboolean relative, input_mouse_callback_t callback,
   166 				void *data )
   167 {
   168     mouse_entry_t ent = malloc( sizeof( struct mouse_entry ) );
   169     assert( ent != NULL );
   170     ent->callback = callback;
   171     ent->data = data;
   172     ent->next = mousehooks;
   173     mousehooks = ent;
   174     return TRUE;
   175 }    
   177 void input_unregister_mouse_hook( input_mouse_callback_t callback, void *data )
   178 {
   179     mouse_entry_t ent = mousehooks;
   180     if( ent != NULL ) {
   181 	mouse_entry_t next = ent->next;
   182 	if( ent->callback == callback && ent->data == data ) {
   183 	    free(ent);
   184 	    mousehooks = next;
   185 	    return;
   186 	}
   187 	while( next != NULL ) {
   188 	    if( next->callback == callback && next->data == data ) {
   189 		ent->next = next->next;
   190 		free(next);
   191 	    }
   192 	}
   193     }
   194 }
   196 void input_event_mouse( uint32_t buttons, int32_t x, int32_t y )
   197 {
   198     mouse_entry_t ent = mousehooks;
   199     while( ent != NULL ) {
   200 	ent->callback(ent->data, buttons, x, y);
   201 	ent = ent->next;
   202     }
   203 }
   205 gboolean input_is_key_valid( const gchar *keysym )
   206 {
   207     if( display_driver == NULL )
   208 	return FALSE; /* No display driver */
   209     return display_driver->resolve_keysym(keysym) != 0;
   210 }
   212 gboolean input_is_key_registered( const gchar *keysym )
   213 {
   214     if( display_driver == NULL )
   215 	return FALSE;
   216     uint16_t keycode = display_driver->resolve_keysym(keysym);
   217     if( keycode == 0 )
   218 	return FALSE;
   219     return input_get_key( keycode ) != NULL;
   220 }
   222 void input_event_keydown( uint16_t keycode )
   223 {
   224     struct keymap_entry *key = input_get_key(keycode);
   225     if( key != NULL ) {
   226 	key->callback( key->data, key->value, TRUE );
   227     }
   228     key = keyhooks;
   229     while( key != NULL ) {
   230 	key->callback( key->data, keycode, TRUE );
   231 	key = key->next;
   232     }
   233 }
   235 void input_event_keyup( uint16_t keycode )
   236 {
   237     struct keymap_entry *key = input_get_key(keycode);
   238     if( key != NULL ) {
   239 	key->callback( key->data, key->value, FALSE );
   240     }
   241     key = keyhooks;
   242     while( key != NULL ) {
   243 	key->callback( key->data, keycode, FALSE );
   244 	key = key->next;
   245     }
   246 }
   248 uint16_t input_keycode_to_dckeysym( uint16_t keycode )
   249 {
   250     return display_driver->convert_to_dckeysym(keycode);
   251 }
   253 display_driver_t get_display_driver_by_name( const char *name )
   254 {
   255     int i;
   256     if( name == NULL ) {
   257 	return display_driver_list[0];
   258     }
   259     for( i=0; display_driver_list[i] != NULL; i++ ) {
   260 	if( strcasecmp( display_driver_list[i]->name, name ) == 0 ) {
   261 	    return display_driver_list[i];
   262 	}
   263     }
   265     return NULL;
   266 }
   269 gboolean display_set_driver( display_driver_t driver )
   270 {
   271     gboolean rv = TRUE;
   272     if( display_driver != NULL && display_driver->shutdown_driver != NULL ) 
   273 	display_driver->shutdown_driver();
   275     display_driver = driver;
   276     if( driver->init_driver != NULL )
   277 	rv = driver->init_driver();
   278     if( !rv ) {
   279 	display_driver = NULL;
   280     }
   281     return rv;
   282 }
.