Search
lxdream.org :: lxdream/src/display.c
lxdream 0.9.1
released Jun 29
Download Now
filename src/display.c
changeset 736:a02d1475ccfd
prev700:4650d0c7f6f9
next770:429ff505c450
author nkeynes
date Mon Jul 14 07:44:42 2008 +0000 (11 years ago)
permissions -rw-r--r--
last change Re-indent everything consistently
Fix include guards for consistency as well
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@681
    27
display_driver_t display_driver_list[] = {
nkeynes@541
    28
#ifdef HAVE_GTK
nkeynes@736
    29
        &display_gtk_driver,
nkeynes@681
    30
#else
nkeynes@681
    31
#ifdef HAVE_COCOA
nkeynes@736
    32
        &display_osx_driver,
nkeynes@541
    33
#endif
nkeynes@681
    34
#endif					   
nkeynes@736
    35
        &display_null_driver,
nkeynes@736
    36
        NULL };
nkeynes@531
    37
nkeynes@614
    38
/* Some explanation:
nkeynes@614
    39
 *   The system has at least one "root" device representing the main display 
nkeynes@614
    40
 * (which may be the null display). This device is part of the display_driver
nkeynes@614
    41
 * and generates events with no input_driver. The root device has no id
nkeynes@614
    42
 * as such (for the purposes of event names)
nkeynes@614
    43
 *
nkeynes@614
    44
 *   The system may also have one or more auxilliary devices which each have
nkeynes@614
    45
 * an input_driver and an id (eg "JS0"). So the keysym "Return" is (de)coded by
nkeynes@614
    46
 * the root device, and the keysym "JS0: Button0" is (de)coded by the JS0 input
nkeynes@614
    47
 * device as "Button0".
nkeynes@614
    48
 *
nkeynes@614
    49
 *   For the moment, mice are handled specially, as they behave a little
nkeynes@614
    50
 * differently from other devices (although this will probably change in the 
nkeynes@614
    51
 * future.
nkeynes@614
    52
 */
nkeynes@614
    53
nkeynes@614
    54
nkeynes@144
    55
typedef struct keymap_entry {
nkeynes@144
    56
    input_key_callback_t callback;
nkeynes@144
    57
    void *data;
nkeynes@144
    58
    uint32_t value;
nkeynes@608
    59
    struct keymap_entry *next; // allow chaining
nkeynes@144
    60
} *keymap_entry_t;
nkeynes@144
    61
nkeynes@608
    62
typedef struct mouse_entry {
nkeynes@608
    63
    gboolean relative;
nkeynes@608
    64
    input_mouse_callback_t callback;
nkeynes@608
    65
    void *data;
nkeynes@608
    66
    struct mouse_entry *next;
nkeynes@608
    67
} *mouse_entry_t;
nkeynes@608
    68
nkeynes@614
    69
typedef struct input_driver_entry {
nkeynes@614
    70
    input_driver_t driver;
nkeynes@614
    71
    uint16_t entry_count;
nkeynes@614
    72
    struct keymap_entry *keymap[0];
nkeynes@614
    73
} *input_driver_entry_t;
nkeynes@614
    74
nkeynes@144
    75
/**
nkeynes@327
    76
 * Colour format information
nkeynes@327
    77
 */
nkeynes@327
    78
struct colour_format colour_formats[] = {
nkeynes@736
    79
        { GL_UNSIGNED_SHORT_1_5_5_5_REV, GL_BGRA, GL_RGB5_A1, 2 },
nkeynes@736
    80
        { GL_UNSIGNED_SHORT_5_6_5, GL_RGB, GL_RGB5, 2 },
nkeynes@736
    81
        { GL_UNSIGNED_SHORT_4_4_4_4_REV, GL_BGRA, GL_RGBA4, 2 },
nkeynes@736
    82
        { GL_UNSIGNED_BYTE, GL_BGRA, GL_RGBA8, 4 }, /* YUV decoded to ARGB8888 */
nkeynes@736
    83
        { GL_UNSIGNED_BYTE, GL_BGR, GL_RGB, 3 },
nkeynes@736
    84
        { GL_UNSIGNED_BYTE, GL_BGRA, GL_RGBA8, 4 },
nkeynes@736
    85
        { GL_UNSIGNED_BYTE, GL_BGRA, GL_RGBA8, 4 }, /* Index4 decoded */
nkeynes@736
    86
        { GL_UNSIGNED_BYTE, GL_BGRA, GL_RGBA8, 4 }, /* Index8 decoded */
nkeynes@736
    87
        { GL_UNSIGNED_BYTE, GL_BGRA, GL_RGBA8, 4 },
nkeynes@736
    88
        { GL_UNSIGNED_BYTE, GL_RGB, GL_RGB, 3 },
nkeynes@736
    89
nkeynes@327
    90
};
nkeynes@327
    91
nkeynes@327
    92
/**
nkeynes@144
    93
 * FIXME: make this more memory efficient
nkeynes@144
    94
 */
nkeynes@614
    95
static struct keymap_entry *root_keymap[65535];
nkeynes@614
    96
static struct keymap_entry *keyhooks = NULL;
nkeynes@614
    97
static struct mouse_entry *mousehooks = NULL;
nkeynes@614
    98
static gboolean display_focused = TRUE;
nkeynes@614
    99
static GList *input_drivers= NULL;
nkeynes@614
   100
static display_keysym_callback_t display_keysym_hook = NULL;
nkeynes@614
   101
void *display_keysym_hook_data;
nkeynes@144
   102
nkeynes@614
   103
gboolean input_register_device( input_driver_t driver, uint16_t max_keycode )
nkeynes@144
   104
{
nkeynes@614
   105
    GList *ptr;
nkeynes@614
   106
    for( ptr = input_drivers; ptr != NULL; ptr = g_list_next(ptr) ) {
nkeynes@736
   107
        input_driver_entry_t entry = (input_driver_entry_t)ptr->data;
nkeynes@736
   108
        if( strcasecmp( entry->driver->id, driver->id ) == 0 ) {
nkeynes@736
   109
            return FALSE;
nkeynes@736
   110
        }
nkeynes@144
   111
    }
nkeynes@614
   112
nkeynes@614
   113
    input_driver_entry_t entry = g_malloc0( sizeof(struct input_driver_entry) + (sizeof(keymap_entry_t) * max_keycode) );
nkeynes@614
   114
    entry->driver = driver;
nkeynes@614
   115
    entry->entry_count = max_keycode;
nkeynes@614
   116
    input_drivers = g_list_append( input_drivers, entry );
nkeynes@614
   117
    return TRUE;
nkeynes@144
   118
}
nkeynes@144
   119
nkeynes@615
   120
gboolean input_has_device( const gchar *id )
nkeynes@615
   121
{
nkeynes@615
   122
    GList *ptr;
nkeynes@615
   123
    for( ptr = input_drivers; ptr != NULL; ptr = g_list_next(ptr) ) {
nkeynes@736
   124
        input_driver_entry_t entry = (input_driver_entry_t)ptr->data;
nkeynes@736
   125
        if( strcasecmp(entry->driver->id, id) == 0 ) {
nkeynes@736
   126
            return TRUE;
nkeynes@736
   127
        }
nkeynes@615
   128
    }
nkeynes@615
   129
    return FALSE;
nkeynes@615
   130
}
nkeynes@615
   131
nkeynes@615
   132
nkeynes@614
   133
void input_unregister_device( input_driver_t driver )
nkeynes@144
   134
{
nkeynes@614
   135
    GList *ptr;
nkeynes@614
   136
    for( ptr = input_drivers; ptr != NULL; ptr = g_list_next(ptr) ) {
nkeynes@736
   137
        input_driver_entry_t entry = (input_driver_entry_t)ptr->data;
nkeynes@736
   138
        if( entry->driver == driver ) {
nkeynes@736
   139
            if( driver->destroy != NULL ) {
nkeynes@736
   140
                driver->destroy(driver);
nkeynes@736
   141
            }
nkeynes@736
   142
            input_drivers = g_list_remove(input_drivers, (gpointer)entry);
nkeynes@736
   143
            g_free( entry );
nkeynes@736
   144
            return;
nkeynes@736
   145
        }
nkeynes@144
   146
    }
nkeynes@144
   147
}
nkeynes@144
   148
nkeynes@614
   149
/**
nkeynes@614
   150
 * Resolve the keysym and return a pointer to the keymap entry pointer
nkeynes@614
   151
 * @return keymap pointer or NULL if the key was unresolved
nkeynes@614
   152
 */
nkeynes@614
   153
static struct keymap_entry **input_entry_from_keysym( const gchar *keysym )
nkeynes@144
   154
{
nkeynes@614
   155
    if( keysym == NULL || keysym[0] == 0 ) {
nkeynes@736
   156
        return NULL;
nkeynes@614
   157
    }
nkeynes@614
   158
    char **strv = g_strsplit(keysym,":",2);
nkeynes@614
   159
    if( strv[1] == NULL ) {
nkeynes@736
   160
        /* root device */
nkeynes@736
   161
        if( display_driver == NULL || display_driver->resolve_keysym == NULL) {
nkeynes@736
   162
            // Root device has no input handling
nkeynes@736
   163
            g_strfreev(strv);
nkeynes@736
   164
            return NULL;
nkeynes@736
   165
        }
nkeynes@736
   166
        uint16_t keycode = display_driver->resolve_keysym(g_strstrip(strv[0]));
nkeynes@736
   167
        g_strfreev(strv);
nkeynes@736
   168
        if( keycode == 0 ) {
nkeynes@736
   169
            return NULL;
nkeynes@736
   170
        }
nkeynes@736
   171
        return &root_keymap[keycode-1];
nkeynes@614
   172
    } else {
nkeynes@736
   173
        char *id = g_strstrip(strv[0]);
nkeynes@736
   174
        GList *ptr;
nkeynes@736
   175
        for( ptr = input_drivers; ptr != NULL; ptr = g_list_next(ptr) ) {
nkeynes@736
   176
            input_driver_entry_t entry = (input_driver_entry_t)ptr->data;
nkeynes@736
   177
            if( strcasecmp( entry->driver->id, id ) == 0 ) {
nkeynes@736
   178
                /* we have ze device */
nkeynes@736
   179
                if( entry->driver->resolve_keysym == NULL ) {
nkeynes@736
   180
                    g_strfreev(strv);
nkeynes@736
   181
                    return NULL;
nkeynes@736
   182
                } 
nkeynes@736
   183
                uint16_t keycode = entry->driver->resolve_keysym(entry->driver, g_strstrip(strv[1]));
nkeynes@736
   184
                g_strfreev(strv);
nkeynes@736
   185
                if( keycode == 0 || keycode > entry->entry_count ) {
nkeynes@736
   186
                    return NULL;
nkeynes@736
   187
                }
nkeynes@736
   188
                return &entry->keymap[keycode-1];
nkeynes@736
   189
            }
nkeynes@736
   190
        }
nkeynes@736
   191
        g_strfreev(strv);
nkeynes@736
   192
        return NULL; // device not found
nkeynes@614
   193
    }
nkeynes@144
   194
}
nkeynes@144
   195
nkeynes@614
   196
static struct keymap_entry **input_entry_from_keycode( input_driver_t driver, uint16_t keycode )
nkeynes@614
   197
{
nkeynes@614
   198
    GList *ptr;
nkeynes@614
   199
nkeynes@614
   200
    if( keycode == 0 ) {
nkeynes@736
   201
        return NULL;
nkeynes@614
   202
    }
nkeynes@614
   203
nkeynes@614
   204
    if( driver == NULL ) {
nkeynes@736
   205
        return &root_keymap[keycode-1];
nkeynes@614
   206
    }
nkeynes@614
   207
nkeynes@614
   208
    for( ptr = input_drivers; ptr != NULL; ptr = g_list_next(ptr) ) {
nkeynes@736
   209
        input_driver_entry_t entry = (input_driver_entry_t)ptr->data;
nkeynes@736
   210
        if( entry->driver == driver ) {
nkeynes@736
   211
            if( keycode > entry->entry_count ) {
nkeynes@736
   212
                return NULL;
nkeynes@736
   213
            } else {
nkeynes@736
   214
                return &entry->keymap[keycode-1];
nkeynes@736
   215
            }
nkeynes@736
   216
        }
nkeynes@614
   217
    }
nkeynes@614
   218
    return NULL;
nkeynes@614
   219
}
nkeynes@614
   220
nkeynes@614
   221
static gchar *input_keysym_for_keycode( input_driver_t driver, uint16_t keycode )
nkeynes@614
   222
{
nkeynes@614
   223
    if( keycode == 0 ) {
nkeynes@736
   224
        return NULL;
nkeynes@614
   225
    }
nkeynes@614
   226
    if( driver == NULL ) {
nkeynes@736
   227
        if( display_driver != NULL && display_driver->get_keysym_for_keycode != NULL ) {
nkeynes@736
   228
            return display_driver->get_keysym_for_keycode(keycode);
nkeynes@736
   229
        }
nkeynes@614
   230
    } else if( driver->get_keysym_for_keycode ) {
nkeynes@736
   231
        gchar *sym = driver->get_keysym_for_keycode(driver,keycode);
nkeynes@736
   232
        if( sym != NULL ) {
nkeynes@736
   233
            gchar *result = g_strdup_printf( "%s: %s", driver->id, sym );
nkeynes@736
   234
            g_free(sym);
nkeynes@736
   235
            return result;
nkeynes@736
   236
        }
nkeynes@614
   237
    }
nkeynes@614
   238
    return NULL;
nkeynes@614
   239
}
nkeynes@614
   240
nkeynes@614
   241
nkeynes@144
   242
gboolean input_register_key( const gchar *keysym, input_key_callback_t callback,
nkeynes@736
   243
                             void *data, uint32_t value )
nkeynes@144
   244
{
nkeynes@614
   245
    if( keysym == NULL ) {
nkeynes@736
   246
        return FALSE;
nkeynes@614
   247
    }
nkeynes@614
   248
    int keys = 0;
nkeynes@271
   249
    gchar **strv = g_strsplit(keysym, ",", 16);
nkeynes@271
   250
    gchar **s = strv;
nkeynes@271
   251
    while( *s != NULL ) {
nkeynes@736
   252
        keymap_entry_t *entryp = input_entry_from_keysym(*s);
nkeynes@736
   253
        if( entryp != NULL ) {
nkeynes@736
   254
            *entryp = g_malloc0(sizeof(struct keymap_entry));
nkeynes@736
   255
            (*entryp)->callback = callback;
nkeynes@736
   256
            (*entryp)->data = data;
nkeynes@736
   257
            (*entryp)->value = value;
nkeynes@736
   258
            keys++;
nkeynes@736
   259
        }
nkeynes@736
   260
        s++;
nkeynes@271
   261
    }
nkeynes@271
   262
    g_strfreev(strv);
nkeynes@614
   263
    return keys != 0;
nkeynes@144
   264
}
nkeynes@144
   265
nkeynes@451
   266
void input_unregister_key( const gchar *keysym, input_key_callback_t callback,
nkeynes@736
   267
                           void *data, uint32_t value )
nkeynes@144
   268
{
nkeynes@614
   269
    if( keysym == NULL ) {
nkeynes@736
   270
        return;
nkeynes@614
   271
    }
nkeynes@614
   272
nkeynes@614
   273
    gchar **strv = g_strsplit(keysym, ",", 16);
nkeynes@614
   274
    gchar **s = strv;
nkeynes@614
   275
    while( *s != NULL ) {
nkeynes@736
   276
        keymap_entry_t *entryp = input_entry_from_keysym(*s);
nkeynes@736
   277
        if( entryp != NULL && *entryp != NULL && (*entryp)->callback == callback &&
nkeynes@736
   278
                (*entryp)->data == data && (*entryp)->value == value ) {
nkeynes@736
   279
            g_free( *entryp );
nkeynes@736
   280
            *entryp = NULL;
nkeynes@736
   281
        }
nkeynes@736
   282
        s++;
nkeynes@614
   283
    }
nkeynes@614
   284
    g_strfreev(strv);
nkeynes@144
   285
}
nkeynes@608
   286
nkeynes@608
   287
gboolean input_register_hook( input_key_callback_t callback,
nkeynes@736
   288
                              void *data )
nkeynes@608
   289
{
nkeynes@608
   290
    keymap_entry_t key = malloc( sizeof( struct keymap_entry ) );
nkeynes@608
   291
    assert( key != NULL );
nkeynes@608
   292
    key->callback = callback;
nkeynes@608
   293
    key->data = data;
nkeynes@608
   294
    key->next = keyhooks;
nkeynes@608
   295
    keyhooks = key;
nkeynes@608
   296
    return TRUE;
nkeynes@608
   297
}
nkeynes@608
   298
nkeynes@608
   299
void input_unregister_hook( input_key_callback_t callback,
nkeynes@736
   300
                            void *data )
nkeynes@608
   301
{
nkeynes@608
   302
    keymap_entry_t key = keyhooks;
nkeynes@608
   303
    if( key != NULL ) {
nkeynes@736
   304
        if( key->callback == callback && key->data == data ) {
nkeynes@736
   305
            keyhooks = keyhooks->next;
nkeynes@736
   306
            free(key);
nkeynes@736
   307
            return;
nkeynes@736
   308
        }
nkeynes@736
   309
        while( key->next != NULL ) {
nkeynes@736
   310
            if( key->next->callback == callback && key->next->data == data ) {
nkeynes@627
   311
                keymap_entry_t next = key->next;
nkeynes@736
   312
                key->next = next->next;
nkeynes@736
   313
                free(next);
nkeynes@736
   314
                return;
nkeynes@736
   315
            }
nkeynes@736
   316
            key = key->next;
nkeynes@736
   317
        }
nkeynes@608
   318
    }
nkeynes@608
   319
}
nkeynes@608
   320
nkeynes@608
   321
gboolean input_register_mouse_hook( gboolean relative, input_mouse_callback_t callback,
nkeynes@736
   322
                                    void *data )
nkeynes@608
   323
{
nkeynes@608
   324
    mouse_entry_t ent = malloc( sizeof( struct mouse_entry ) );
nkeynes@608
   325
    assert( ent != NULL );
nkeynes@608
   326
    ent->callback = callback;
nkeynes@608
   327
    ent->data = data;
nkeynes@608
   328
    ent->next = mousehooks;
nkeynes@608
   329
    mousehooks = ent;
nkeynes@608
   330
    return TRUE;
nkeynes@608
   331
}    
nkeynes@608
   332
nkeynes@608
   333
void input_unregister_mouse_hook( input_mouse_callback_t callback, void *data )
nkeynes@608
   334
{
nkeynes@608
   335
    mouse_entry_t ent = mousehooks;
nkeynes@608
   336
    if( ent != NULL ) {
nkeynes@736
   337
        if( ent->callback == callback && ent->data == data ) {
nkeynes@736
   338
            mousehooks = mousehooks->next;
nkeynes@736
   339
            free(ent);
nkeynes@736
   340
            return;
nkeynes@736
   341
        }
nkeynes@736
   342
        while( ent->next != NULL ) {
nkeynes@736
   343
            if( ent->next->callback == callback && ent->next->data == data ) {
nkeynes@627
   344
                mouse_entry_t next = ent->next;
nkeynes@736
   345
                ent->next = next->next;
nkeynes@736
   346
                free(next);
nkeynes@736
   347
                return;
nkeynes@736
   348
            }
nkeynes@736
   349
            ent = ent->next;
nkeynes@736
   350
        }
nkeynes@608
   351
    }
nkeynes@608
   352
}
nkeynes@608
   353
nkeynes@608
   354
void input_event_mouse( uint32_t buttons, int32_t x, int32_t y )
nkeynes@608
   355
{
nkeynes@608
   356
    mouse_entry_t ent = mousehooks;
nkeynes@608
   357
    while( ent != NULL ) {
nkeynes@736
   358
        ent->callback(ent->data, buttons, x, y);
nkeynes@736
   359
        ent = ent->next;
nkeynes@608
   360
    }
nkeynes@608
   361
}
nkeynes@144
   362
nkeynes@144
   363
gboolean input_is_key_valid( const gchar *keysym )
nkeynes@144
   364
{
nkeynes@614
   365
    keymap_entry_t *ptr = input_entry_from_keysym(keysym);
nkeynes@614
   366
    return ptr != NULL;
nkeynes@144
   367
}
nkeynes@144
   368
nkeynes@144
   369
gboolean input_is_key_registered( const gchar *keysym )
nkeynes@144
   370
{
nkeynes@614
   371
    keymap_entry_t *ptr = input_entry_from_keysym(keysym);
nkeynes@614
   372
    return ptr != NULL && *ptr != NULL;
nkeynes@144
   373
}
nkeynes@144
   374
nkeynes@614
   375
void input_event_keydown( input_driver_t driver, uint16_t keycode, uint32_t pressure )
nkeynes@144
   376
{
nkeynes@614
   377
    if( display_focused ) {
nkeynes@736
   378
        keymap_entry_t *entryp = input_entry_from_keycode(driver,keycode);
nkeynes@736
   379
        if( entryp != NULL && *entryp != NULL ) {
nkeynes@736
   380
            (*entryp)->callback( (*entryp)->data, (*entryp)->value, pressure, TRUE );
nkeynes@736
   381
        }
nkeynes@736
   382
        keymap_entry_t key = keyhooks;
nkeynes@736
   383
        while( key != NULL ) {
nkeynes@736
   384
            key->callback( key->data, keycode, pressure, TRUE );
nkeynes@736
   385
            key = key->next;
nkeynes@736
   386
        }
nkeynes@608
   387
    }
nkeynes@614
   388
    if( display_keysym_hook != NULL ) {
nkeynes@736
   389
        gchar *sym = input_keysym_for_keycode( driver, keycode );
nkeynes@736
   390
        if( sym != NULL ) {
nkeynes@736
   391
            display_keysym_hook(display_keysym_hook_data, sym);
nkeynes@736
   392
            g_free(sym);
nkeynes@736
   393
        }
nkeynes@608
   394
    }
nkeynes@144
   395
}
nkeynes@144
   396
nkeynes@614
   397
void input_event_keyup( input_driver_t driver, uint16_t keycode, uint32_t pressure )
nkeynes@144
   398
{
nkeynes@614
   399
    if( display_focused ) {
nkeynes@736
   400
        keymap_entry_t *entryp = input_entry_from_keycode(driver,keycode);
nkeynes@736
   401
        if( entryp != NULL && *entryp != NULL ) {
nkeynes@736
   402
            (*entryp)->callback( (*entryp)->data, (*entryp)->value, pressure, FALSE );
nkeynes@736
   403
        }
nkeynes@614
   404
nkeynes@736
   405
        keymap_entry_t key = keyhooks;
nkeynes@736
   406
        while( key != NULL ) {
nkeynes@736
   407
            key->callback( key->data, keycode, pressure, FALSE );
nkeynes@736
   408
            key = key->next;
nkeynes@736
   409
        }
nkeynes@608
   410
    }
nkeynes@608
   411
}
nkeynes@608
   412
nkeynes@608
   413
uint16_t input_keycode_to_dckeysym( uint16_t keycode )
nkeynes@608
   414
{
nkeynes@608
   415
    return display_driver->convert_to_dckeysym(keycode);
nkeynes@144
   416
}
nkeynes@144
   417
nkeynes@700
   418
void print_display_drivers( FILE *out )
nkeynes@700
   419
{
nkeynes@700
   420
    int i;
nkeynes@700
   421
    fprintf( out, "Available video drivers:\n" );
nkeynes@700
   422
    for( i=0; display_driver_list[i] != NULL; i++ ) {
nkeynes@700
   423
        fprintf( out, "  %-8s %s\n", display_driver_list[i]->name,
nkeynes@736
   424
                gettext(display_driver_list[i]->description) );
nkeynes@700
   425
    }
nkeynes@700
   426
}
nkeynes@700
   427
nkeynes@531
   428
display_driver_t get_display_driver_by_name( const char *name )
nkeynes@531
   429
{
nkeynes@531
   430
    int i;
nkeynes@531
   431
    if( name == NULL ) {
nkeynes@736
   432
        return display_driver_list[0];
nkeynes@531
   433
    }
nkeynes@531
   434
    for( i=0; display_driver_list[i] != NULL; i++ ) {
nkeynes@736
   435
        if( strcasecmp( display_driver_list[i]->name, name ) == 0 ) {
nkeynes@736
   436
            return display_driver_list[i];
nkeynes@736
   437
        }
nkeynes@531
   438
    }
nkeynes@531
   439
nkeynes@531
   440
    return NULL;
nkeynes@531
   441
}
nkeynes@144
   442
nkeynes@144
   443
nkeynes@370
   444
gboolean display_set_driver( display_driver_t driver )
nkeynes@144
   445
{
nkeynes@370
   446
    gboolean rv = TRUE;
nkeynes@370
   447
    if( display_driver != NULL && display_driver->shutdown_driver != NULL ) 
nkeynes@736
   448
        display_driver->shutdown_driver();
nkeynes@144
   449
nkeynes@144
   450
    display_driver = driver;
nkeynes@144
   451
    if( driver->init_driver != NULL )
nkeynes@736
   452
        rv = driver->init_driver();
nkeynes@531
   453
    if( !rv ) {
nkeynes@736
   454
        display_driver = NULL;
nkeynes@370
   455
    }
nkeynes@370
   456
    return rv;
nkeynes@144
   457
}
nkeynes@614
   458
nkeynes@614
   459
void display_set_focused( gboolean has_focus )
nkeynes@614
   460
{
nkeynes@614
   461
    display_focused = has_focus;
nkeynes@614
   462
}
nkeynes@614
   463
nkeynes@614
   464
void input_set_keysym_hook( display_keysym_callback_t hook, void *data )
nkeynes@614
   465
{
nkeynes@614
   466
    display_keysym_hook = hook;
nkeynes@614
   467
    display_keysym_hook_data = data;
nkeynes@614
   468
}
.