1.1 --- a/src/display.c Sat Jan 26 02:45:27 2008 +0000
1.2 +++ b/src/display.c Mon Jan 28 02:38:09 2008 +0000
1.4 &display_null_driver,
1.7 +/* Some explanation:
1.8 + * The system has at least one "root" device representing the main display
1.9 + * (which may be the null display). This device is part of the display_driver
1.10 + * and generates events with no input_driver. The root device has no id
1.11 + * as such (for the purposes of event names)
1.13 + * The system may also have one or more auxilliary devices which each have
1.14 + * an input_driver and an id (eg "JS0"). So the keysym "Return" is (de)coded by
1.15 + * the root device, and the keysym "JS0: Button0" is (de)coded by the JS0 input
1.16 + * device as "Button0".
1.18 + * For the moment, mice are handled specially, as they behave a little
1.19 + * differently from other devices (although this will probably change in the
1.24 typedef struct keymap_entry {
1.26 input_key_callback_t callback;
1.30 struct mouse_entry *next;
1.33 +typedef struct input_driver_entry {
1.34 + input_driver_t driver;
1.35 + uint16_t entry_count;
1.36 + struct keymap_entry *keymap[0];
1.37 +} *input_driver_entry_t;
1.40 * Colour format information
1.42 @@ -66,68 +88,183 @@
1.44 * FIXME: make this more memory efficient
1.46 -struct keymap_entry *keymap[65536];
1.47 -struct keymap_entry *keyhooks = NULL;
1.48 -struct mouse_entry *mousehooks = NULL;
1.49 +static struct keymap_entry *root_keymap[65535];
1.50 +static struct keymap_entry *keyhooks = NULL;
1.51 +static struct mouse_entry *mousehooks = NULL;
1.52 +static gboolean display_focused = TRUE;
1.53 +static GList *input_drivers= NULL;
1.54 +static display_keysym_callback_t display_keysym_hook = NULL;
1.55 +void *display_keysym_hook_data;
1.57 -static struct keymap_entry *input_create_key( uint16_t keycode )
1.58 +gboolean input_register_device( input_driver_t driver, uint16_t max_keycode )
1.60 - struct keymap_entry *key = keymap[ keycode ];
1.61 - if( key == NULL ) {
1.62 - key = malloc( sizeof( struct keymap_entry ) );
1.63 - assert( key != NULL );
1.64 - keymap[ keycode ] = key;
1.65 - key->keycode = keycode;
1.67 + for( ptr = input_drivers; ptr != NULL; ptr = g_list_next(ptr) ) {
1.68 + input_driver_entry_t entry = (input_driver_entry_t)ptr->data;
1.69 + if( strcasecmp( entry->driver->id, driver->id ) == 0 ) {
1.75 + input_driver_entry_t entry = g_malloc0( sizeof(struct input_driver_entry) + (sizeof(keymap_entry_t) * max_keycode) );
1.76 + entry->driver = driver;
1.77 + entry->entry_count = max_keycode;
1.78 + input_drivers = g_list_append( input_drivers, entry );
1.82 -static void input_delete_key( uint16_t keycode, input_key_callback_t callback, void *data,
1.84 +void input_unregister_device( input_driver_t driver )
1.86 - struct keymap_entry *key = keymap[keycode];
1.87 - if( key != NULL && key->callback == callback && key->data == data && key->value == value ) {
1.89 - keymap[keycode] = NULL;
1.91 + for( ptr = input_drivers; ptr != NULL; ptr = g_list_next(ptr) ) {
1.92 + input_driver_entry_t entry = (input_driver_entry_t)ptr->data;
1.93 + if( entry->driver == driver ) {
1.94 + if( driver->destroy != NULL ) {
1.95 + driver->destroy(driver);
1.97 + input_drivers = g_list_remove(input_drivers, (gpointer)entry);
1.104 -static struct keymap_entry *input_get_key( uint16_t keycode )
1.106 + * Resolve the keysym and return a pointer to the keymap entry pointer
1.107 + * @return keymap pointer or NULL if the key was unresolved
1.109 +static struct keymap_entry **input_entry_from_keysym( const gchar *keysym )
1.111 - return keymap[ keycode ];
1.112 + if( keysym == NULL || keysym[0] == 0 ) {
1.115 + char **strv = g_strsplit(keysym,":",2);
1.116 + if( strv[1] == NULL ) {
1.117 + /* root device */
1.118 + if( display_driver == NULL || display_driver->resolve_keysym == NULL) {
1.119 + // Root device has no input handling
1.120 + g_strfreev(strv);
1.123 + uint16_t keycode = display_driver->resolve_keysym(g_strstrip(strv[0]));
1.124 + g_strfreev(strv);
1.125 + if( keycode == 0 ) {
1.128 + return &root_keymap[keycode-1];
1.130 + char *id = g_strstrip(strv[0]);
1.132 + for( ptr = input_drivers; ptr != NULL; ptr = g_list_next(ptr) ) {
1.133 + input_driver_entry_t entry = (input_driver_entry_t)ptr->data;
1.134 + if( strcasecmp( entry->driver->id, id ) == 0 ) {
1.135 + /* we have ze device */
1.136 + if( entry->driver->resolve_keysym == NULL ) {
1.137 + g_strfreev(strv);
1.140 + uint16_t keycode = entry->driver->resolve_keysym(entry->driver, g_strstrip(strv[1]));
1.141 + g_strfreev(strv);
1.142 + if( keycode == 0 || keycode > entry->entry_count ) {
1.145 + return &entry->keymap[keycode-1];
1.148 + g_strfreev(strv);
1.149 + return NULL; // device not found
1.153 +static struct keymap_entry **input_entry_from_keycode( input_driver_t driver, uint16_t keycode )
1.157 + if( keycode == 0 ) {
1.161 + if( driver == NULL ) {
1.162 + return &root_keymap[keycode-1];
1.165 + for( ptr = input_drivers; ptr != NULL; ptr = g_list_next(ptr) ) {
1.166 + input_driver_entry_t entry = (input_driver_entry_t)ptr->data;
1.167 + if( entry->driver == driver ) {
1.168 + if( keycode > entry->entry_count ) {
1.171 + return &entry->keymap[keycode-1];
1.178 +static gchar *input_keysym_for_keycode( input_driver_t driver, uint16_t keycode )
1.180 + if( keycode == 0 ) {
1.183 + if( driver == NULL ) {
1.184 + if( display_driver != NULL && display_driver->get_keysym_for_keycode != NULL ) {
1.185 + return display_driver->get_keysym_for_keycode(keycode);
1.187 + } else if( driver->get_keysym_for_keycode ) {
1.188 + gchar *sym = driver->get_keysym_for_keycode(driver,keycode);
1.189 + if( sym != NULL ) {
1.190 + gchar *result = g_strdup_printf( "%s: %s", driver->id, sym );
1.199 gboolean input_register_key( const gchar *keysym, input_key_callback_t callback,
1.200 void *data, uint32_t value )
1.202 - if( display_driver == NULL || keysym == NULL || display_driver->resolve_keysym == NULL )
1.203 - return FALSE; /* No display driver */
1.204 + if( keysym == NULL ) {
1.208 gchar **strv = g_strsplit(keysym, ",", 16);
1.210 while( *s != NULL ) {
1.211 - uint16_t keycode = display_driver->resolve_keysym(g_strstrip(*s));
1.212 - if( keycode == 0 )
1.213 - return FALSE; /* Invalid keysym */
1.215 - struct keymap_entry *key = input_create_key( keycode );
1.216 - key->callback = callback;
1.217 - key->data = data;
1.218 - key->value = value;
1.219 + keymap_entry_t *entryp = input_entry_from_keysym(*s);
1.220 + if( entryp != NULL ) {
1.221 + *entryp = g_malloc0(sizeof(struct keymap_entry));
1.222 + (*entryp)->callback = callback;
1.223 + (*entryp)->data = data;
1.224 + (*entryp)->value = value;
1.231 + return keys != 0;
1.234 void input_unregister_key( const gchar *keysym, input_key_callback_t callback,
1.235 void *data, uint32_t value )
1.237 - if( display_driver == NULL || keysym == NULL || display_driver->resolve_keysym == NULL )
1.238 + if( keysym == NULL ) {
1.240 - uint16_t keycode = display_driver->resolve_keysym(keysym);
1.241 - if( keycode == 0 )
1.243 - input_delete_key( keycode, callback, data, value );
1.246 + gchar **strv = g_strsplit(keysym, ",", 16);
1.247 + gchar **s = strv;
1.248 + while( *s != NULL ) {
1.249 + keymap_entry_t *entryp = input_entry_from_keysym(*s);
1.250 + if( entryp != NULL && *entryp != NULL && (*entryp)->callback == callback &&
1.251 + (*entryp)->data == data && (*entryp)->value == value ) {
1.252 + g_free( *entryp );
1.257 + g_strfreev(strv);
1.260 gboolean input_register_hook( input_key_callback_t callback,
1.261 @@ -204,44 +341,51 @@
1.263 gboolean input_is_key_valid( const gchar *keysym )
1.265 - if( display_driver == NULL )
1.266 - return FALSE; /* No display driver */
1.267 - return display_driver->resolve_keysym(keysym) != 0;
1.268 + keymap_entry_t *ptr = input_entry_from_keysym(keysym);
1.269 + return ptr != NULL;
1.272 gboolean input_is_key_registered( const gchar *keysym )
1.274 - if( display_driver == NULL )
1.276 - uint16_t keycode = display_driver->resolve_keysym(keysym);
1.277 - if( keycode == 0 )
1.279 - return input_get_key( keycode ) != NULL;
1.280 + keymap_entry_t *ptr = input_entry_from_keysym(keysym);
1.281 + return ptr != NULL && *ptr != NULL;
1.284 -void input_event_keydown( uint16_t keycode )
1.285 +void input_event_keydown( input_driver_t driver, uint16_t keycode, uint32_t pressure )
1.287 - struct keymap_entry *key = input_get_key(keycode);
1.288 - if( key != NULL ) {
1.289 - key->callback( key->data, key->value, TRUE );
1.290 + if( display_focused ) {
1.291 + keymap_entry_t *entryp = input_entry_from_keycode(driver,keycode);
1.292 + if( entryp != NULL && *entryp != NULL ) {
1.293 + (*entryp)->callback( (*entryp)->data, (*entryp)->value, pressure, TRUE );
1.295 + keymap_entry_t key = keyhooks;
1.296 + while( key != NULL ) {
1.297 + key->callback( key->data, keycode, pressure, TRUE );
1.302 - while( key != NULL ) {
1.303 - key->callback( key->data, keycode, TRUE );
1.305 + if( display_keysym_hook != NULL ) {
1.306 + gchar *sym = input_keysym_for_keycode( driver, keycode );
1.307 + if( sym != NULL ) {
1.308 + display_keysym_hook(display_keysym_hook_data, sym);
1.314 -void input_event_keyup( uint16_t keycode )
1.315 +void input_event_keyup( input_driver_t driver, uint16_t keycode, uint32_t pressure )
1.317 - struct keymap_entry *key = input_get_key(keycode);
1.318 - if( key != NULL ) {
1.319 - key->callback( key->data, key->value, FALSE );
1.322 - while( key != NULL ) {
1.323 - key->callback( key->data, keycode, FALSE );
1.325 + if( display_focused ) {
1.326 + keymap_entry_t *entryp = input_entry_from_keycode(driver,keycode);
1.327 + if( entryp != NULL && *entryp != NULL ) {
1.328 + (*entryp)->callback( (*entryp)->data, (*entryp)->value, pressure, FALSE );
1.331 + keymap_entry_t key = keyhooks;
1.332 + while( key != NULL ) {
1.333 + key->callback( key->data, keycode, pressure, FALSE );
1.339 @@ -280,3 +424,14 @@
1.344 +void display_set_focused( gboolean has_focus )
1.346 + display_focused = has_focus;
1.349 +void input_set_keysym_hook( display_keysym_callback_t hook, void *data )
1.351 + display_keysym_hook = hook;
1.352 + display_keysym_hook_data = data;