Search
lxdream.org :: lxdream/src/drivers/video_gtk.c
lxdream 0.9.1
released Jun 29
Download Now
filename src/drivers/video_gtk.c
changeset 144:7f0714e89aaa
prev112:a3008ac0765a
next160:17c4c0e4f9ce
author nkeynes
date Mon May 15 08:28:52 2006 +0000 (13 years ago)
permissions -rw-r--r--
last change Rename video_driver to display_driver
Add input source to display
Implement configuration file support
Hook controllers up to configuration
file annotate diff log raw
nkeynes@94
     1
/**
nkeynes@144
     2
 * $Id: video_gtk.c,v 1.6 2006-05-15 08:28:52 nkeynes Exp $
nkeynes@94
     3
 *
nkeynes@94
     4
 * The PC side of the video support (responsible for actually displaying / 
nkeynes@94
     5
 * rendering frames)
nkeynes@94
     6
 *
nkeynes@94
     7
 * Copyright (c) 2005 Nathan Keynes.
nkeynes@94
     8
 *
nkeynes@94
     9
 * This program is free software; you can redistribute it and/or modify
nkeynes@94
    10
 * it under the terms of the GNU General Public License as published by
nkeynes@94
    11
 * the Free Software Foundation; either version 2 of the License, or
nkeynes@94
    12
 * (at your option) any later version.
nkeynes@94
    13
 *
nkeynes@94
    14
 * This program is distributed in the hope that it will be useful,
nkeynes@94
    15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
nkeynes@94
    16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
nkeynes@94
    17
 * GNU General Public License for more details.
nkeynes@94
    18
 */
nkeynes@94
    19
nkeynes@94
    20
#include <gnome.h>
nkeynes@94
    21
#include <gdk/gdkx.h>
nkeynes@94
    22
#include <stdint.h>
nkeynes@144
    23
#include "display.h"
nkeynes@94
    24
#include "drivers/video_x11.h"
nkeynes@94
    25
nkeynes@94
    26
GdkImage *video_img = NULL;
nkeynes@94
    27
GtkWindow *video_win = NULL;
nkeynes@94
    28
GtkWidget *video_area = NULL;
nkeynes@94
    29
uint32_t video_width = 640;
nkeynes@94
    30
uint32_t video_height = 480;
nkeynes@94
    31
uint32_t video_frame_count = 0;
nkeynes@94
    32
nkeynes@144
    33
uint16_t video_gtk_resolve_keysym( const gchar *keysym );
nkeynes@94
    34
gboolean video_gtk_set_output_format( uint32_t width, uint32_t height,  
nkeynes@94
    35
				      int colour_format );
nkeynes@108
    36
gboolean video_gtk_set_render_format( uint32_t width, uint32_t height,  
nkeynes@144
    37
				      int colour_format, gboolean texture );
nkeynes@94
    38
gboolean video_gtk_display_frame( video_buffer_t frame );
nkeynes@94
    39
gboolean video_gtk_blank( uint32_t rgb );
nkeynes@94
    40
nkeynes@144
    41
struct display_driver display_gtk_driver = { "gtk", 
nkeynes@144
    42
					   NULL,
nkeynes@144
    43
					   NULL,
nkeynes@144
    44
					   video_gtk_resolve_keysym,
nkeynes@144
    45
					   video_gtk_set_output_format,
nkeynes@144
    46
					   video_gtk_set_render_format,
nkeynes@144
    47
					   video_gtk_display_frame,
nkeynes@144
    48
					   video_gtk_blank,
nkeynes@144
    49
					   video_glx_swap_buffers };
nkeynes@144
    50
nkeynes@144
    51
gboolean video_gtk_keydown_callback(GtkWidget       *widget,
nkeynes@144
    52
				     GdkEventKey     *event,
nkeynes@144
    53
				     gpointer         user_data)
nkeynes@144
    54
{
nkeynes@144
    55
    input_event_keydown( event->keyval );
nkeynes@144
    56
}
nkeynes@144
    57
nkeynes@144
    58
uint16_t video_gtk_resolve_keysym( const gchar *keysym )
nkeynes@144
    59
{
nkeynes@144
    60
    int val = gdk_keyval_from_name( keysym );
nkeynes@144
    61
    if( val == GDK_VoidSymbol )
nkeynes@144
    62
	return 0;
nkeynes@144
    63
    return (uint16_t)val;
nkeynes@144
    64
}
nkeynes@144
    65
nkeynes@144
    66
gboolean video_gtk_keyup_callback(GtkWidget       *widget,
nkeynes@144
    67
				  GdkEventKey     *event,
nkeynes@144
    68
				  gpointer         user_data)
nkeynes@144
    69
{
nkeynes@144
    70
    input_event_keyup( event->keyval );
nkeynes@144
    71
}
nkeynes@94
    72
nkeynes@94
    73
gboolean video_gtk_set_output_format( uint32_t width, uint32_t height,  
nkeynes@94
    74
				      int colour_format )
nkeynes@94
    75
{
nkeynes@94
    76
    video_width = width;
nkeynes@94
    77
    video_height = height;
nkeynes@94
    78
    if( video_win == NULL ) {
nkeynes@94
    79
	video_win = GTK_WINDOW(gtk_window_new( GTK_WINDOW_TOPLEVEL ));
nkeynes@94
    80
	gtk_window_set_title( video_win, "DreamOn! - Emulation Window" );
nkeynes@94
    81
	gtk_window_set_policy( video_win, FALSE, FALSE, FALSE );
nkeynes@94
    82
	gtk_window_set_default_size( video_win, width, height );
nkeynes@94
    83
    
nkeynes@144
    84
	g_signal_connect( video_win, "key_press_event", 
nkeynes@144
    85
			  G_CALLBACK(video_gtk_keydown_callback), NULL );
nkeynes@144
    86
	g_signal_connect( video_win, "key_release_event", 
nkeynes@144
    87
			  G_CALLBACK(video_gtk_keyup_callback), NULL );
nkeynes@144
    88
	gtk_widget_add_events( GTK_WIDGET(video_win), 
nkeynes@144
    89
			       GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK |
nkeynes@144
    90
			       GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK );
nkeynes@94
    91
	video_area = gtk_image_new();
nkeynes@94
    92
	gtk_widget_show( GTK_WIDGET(video_area) );
nkeynes@94
    93
	gtk_container_add( GTK_CONTAINER(video_win), GTK_WIDGET(video_area) );
nkeynes@94
    94
	gtk_widget_show( GTK_WIDGET(video_win) );
nkeynes@94
    95
	video_x11_set_display( gdk_x11_display_get_xdisplay( gtk_widget_get_display(video_area)),
nkeynes@94
    96
			       gdk_x11_screen_get_xscreen( gtk_widget_get_screen(video_area)),
nkeynes@94
    97
			       GDK_WINDOW_XWINDOW( GTK_WIDGET(video_win)->window ) );
nkeynes@94
    98
			       
nkeynes@94
    99
    }
nkeynes@94
   100
    gtk_window_set_default_size( video_win, width, height );
nkeynes@94
   101
    video_img = gdk_image_new( GDK_IMAGE_FASTEST, gdk_visual_get_system(),
nkeynes@94
   102
			       width, height );
nkeynes@94
   103
    gtk_image_set_from_image( GTK_IMAGE(video_area), video_img, NULL );
nkeynes@94
   104
    /* Note old image is auto de-refed */
nkeynes@94
   105
    return TRUE;
nkeynes@94
   106
}
nkeynes@94
   107
nkeynes@94
   108
nkeynes@94
   109
/**
nkeynes@94
   110
 * Fill the entire frame with the specified colour (00RRGGBB)
nkeynes@94
   111
 */
nkeynes@94
   112
gboolean video_gtk_blank( uint32_t colour ) 
nkeynes@94
   113
{
nkeynes@94
   114
    char *p = video_img->mem;
nkeynes@94
   115
    int i;
nkeynes@94
   116
    for( i=0; i<video_width*video_height; i++ ) {
nkeynes@94
   117
	*p++ = (colour>>16) & 0xFF;
nkeynes@94
   118
	*p++ = (colour>>8) & 0xFF;
nkeynes@94
   119
	*p++ = (colour) & 0xFF;
nkeynes@94
   120
	*p++ = 0;
nkeynes@94
   121
    }
nkeynes@94
   122
}
nkeynes@94
   123
nkeynes@94
   124
gboolean video_gtk_display_frame( video_buffer_t frame ) 
nkeynes@94
   125
{
nkeynes@94
   126
    uint32_t bytes_per_line, x, y;
nkeynes@94
   127
    char *src = frame->data;
nkeynes@94
   128
    char *dest = video_img->mem;
nkeynes@94
   129
nkeynes@112
   130
    return video_glx_display_frame( frame );
nkeynes@112
   131
nkeynes@94
   132
    switch( frame->colour_format ) {
nkeynes@103
   133
    case COLFMT_ARGB1555:
nkeynes@94
   134
	for( y=0; y < frame->vres; y++ ) {
nkeynes@94
   135
	    uint16_t *p = (uint16_t *)src;
nkeynes@103
   136
	    for( x=0; x < frame->hres; x++ ) {
nkeynes@94
   137
		uint16_t pixel = *p++;
nkeynes@94
   138
		*dest++ = (pixel & 0x1F) << 3;
nkeynes@94
   139
		*dest++ = (pixel & 0x3E0) >> 2;
nkeynes@94
   140
		*dest++ = (pixel & 0x7C00) >> 7;
nkeynes@94
   141
		*dest++ = 0;
nkeynes@94
   142
	    }
nkeynes@94
   143
	    src += frame->rowstride;
nkeynes@94
   144
	}
nkeynes@94
   145
	break;
nkeynes@103
   146
    case COLFMT_RGB565:
nkeynes@94
   147
	for( y=0; y < frame->vres; y++ ) {
nkeynes@94
   148
	    uint16_t *p = (uint16_t *)src;
nkeynes@103
   149
	    for( x=0; x < frame->hres; x++ ) {
nkeynes@94
   150
		uint16_t pixel = *p++;
nkeynes@94
   151
		*dest++ = (pixel & 0x1F) << 3;
nkeynes@94
   152
		*dest++ = (pixel & 0x7E0) >> 3;
nkeynes@94
   153
		*dest++ = (pixel & 0xF800) >> 8;
nkeynes@94
   154
		*dest++ = 0;
nkeynes@94
   155
	    }
nkeynes@94
   156
	    src += frame->rowstride;
nkeynes@94
   157
	}
nkeynes@94
   158
	break;
nkeynes@103
   159
    case COLFMT_RGB888:
nkeynes@103
   160
	for( y=0; y< frame->vres; y++ ) {
nkeynes@103
   161
	    char *p = src;
nkeynes@103
   162
	    for( x=0; x < frame->hres; x++ ) {
nkeynes@103
   163
		*dest++ = *p++;
nkeynes@103
   164
		*dest++ = *p++;
nkeynes@103
   165
		*dest++ = *p++;
nkeynes@103
   166
		*dest++ = 0;
nkeynes@103
   167
	    }
nkeynes@103
   168
	    src += frame->rowstride;
nkeynes@103
   169
	}
nkeynes@103
   170
	break;
nkeynes@103
   171
    case COLFMT_ARGB8888:
nkeynes@94
   172
	bytes_per_line = frame->hres << 2;
nkeynes@94
   173
	if( bytes_per_line == frame->rowstride ) {
nkeynes@94
   174
	    /* A little bit faster */
nkeynes@94
   175
	    memcpy( dest, src, bytes_per_line * frame->vres );
nkeynes@94
   176
	} else {
nkeynes@94
   177
	    for( y=0; y< frame->vres; y++ ) {
nkeynes@94
   178
		memcpy( dest, src, bytes_per_line );
nkeynes@94
   179
		src += frame->rowstride;
nkeynes@94
   180
		dest += bytes_per_line;
nkeynes@94
   181
	    }
nkeynes@94
   182
	}
nkeynes@94
   183
	break;
nkeynes@94
   184
    }
nkeynes@94
   185
    gtk_widget_queue_draw( video_area );
nkeynes@94
   186
    return TRUE;
nkeynes@94
   187
}
nkeynes@94
   188
nkeynes@108
   189
gboolean video_gtk_set_render_format( uint32_t width, uint32_t height,  
nkeynes@144
   190
				      int colour_format, gboolean texture )
nkeynes@108
   191
{
nkeynes@108
   192
    return video_glx_set_render_format( 0, 0, width, height );
nkeynes@108
   193
}
.