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