Search
lxdream.org :: lxdream/src/drivers/video_gdk.c
lxdream 0.9.1
released Jun 29
Download Now
filename src/drivers/video_gdk.c
changeset 736:a02d1475ccfd
prev669:ab344e42bca9
next1066:ddffe9d2b332
author nkeynes
date Wed Jul 30 03:00:40 2008 +0000 (15 years ago)
permissions -rw-r--r--
last change Add debian changelog file
view annotate diff log raw
     1 /**
     2  * $Id$
     3  *
     4  * The PC side of the video support (responsible for actually displaying / 
     5  * rendering frames)
     6  *
     7  * Copyright (c) 2005 Nathan Keynes.
     8  *
     9  * This program is free software; you can redistribute it and/or modify
    10  * it under the terms of the GNU General Public License as published by
    11  * the Free Software Foundation; either version 2 of the License, or
    12  * (at your option) any later version.
    13  *
    14  * This program is distributed in the hope that it will be useful,
    15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    17  * GNU General Public License for more details.
    18  */
    19 #include <assert.h>
    20 #include <stdlib.h>
    21 #include <gdk/gdk.h>
    22 #include <gdk-pixbuf/gdk-pixbuf.h>
    23 #include <gtk/gtkwidget.h>
    24 #include <GL/glu.h>
    25 #include <GL/osmesa.h>
    26 #include "lxdream.h"
    27 #include "display.h"
    29 #define MAX_PIXBUF 16
    31 extern GtkWidget *gtk_video_drawable;
    32 extern int video_width, video_height;
    34 static render_buffer_t gdk_pixbuf_create_render_buffer( uint32_t width, uint32_t height );
    35 static void gdk_pixbuf_destroy_render_buffer( render_buffer_t buffer );
    36 static gboolean gdk_pixbuf_set_render_target( render_buffer_t buffer );
    37 static void gdk_pixbuf_display_render_buffer( render_buffer_t buffer );
    38 static void gdk_pixbuf_load_frame_buffer( frame_buffer_t frame, render_buffer_t buffer );
    39 static void gdk_pixbuf_display_blank( uint32_t colour );
    40 static gboolean gdk_pixbuf_read_render_buffer( unsigned char *target, render_buffer_t buffer, int rowstride, int format );
    42 static void *pixbuf_array[MAX_PIXBUF];
    43 unsigned int pixbuf_max = 0;
    44 OSMesaContext osmesa_context = NULL;
    46 void video_gdk_init_driver( display_driver_t driver )
    47 {
    48     pixbuf_max = 0;
    49     driver->create_render_buffer = gdk_pixbuf_create_render_buffer;
    50     driver->destroy_render_buffer = gdk_pixbuf_destroy_render_buffer;
    51     driver->set_render_target = gdk_pixbuf_set_render_target;
    52     driver->display_render_buffer = gdk_pixbuf_display_render_buffer;
    53     driver->load_frame_buffer = gdk_pixbuf_load_frame_buffer;
    54     driver->display_blank = gdk_pixbuf_display_blank;
    55     driver->read_render_buffer = gdk_pixbuf_read_render_buffer;
    57     osmesa_context = OSMesaCreateContextExt( OSMESA_RGBA, 32, 0, 0, 0 );
    58     OSMesaMakeCurrent( osmesa_context, NULL, GL_UNSIGNED_BYTE, 640, 480 );
    59     pvr2_setup_gl_context();
    60 }
    62 int video_gdk_find_free()
    63 {
    64     unsigned int i;
    65     for( i=0; i<pixbuf_max; i++ ) {
    66         if( pixbuf_array[i] == NULL ) {
    67             return i;
    68         }
    69     }
    70     if( i < MAX_PIXBUF ) {
    71         return pixbuf_max++;
    72     }
    73     return -1;
    74 }
    76 void video_gdk_shutdown()
    77 {
    78     unsigned int i;
    79     for( i=0; i<pixbuf_max; i++ ) {
    80         if( pixbuf_array[i] != NULL ) {
    81             g_free(pixbuf_array[i]);
    82             pixbuf_array[i] = NULL;
    83         }
    84     }
    85     pixbuf_max = 0;
    86     OSMesaDestroyContext( osmesa_context );
    87 }
    90 static render_buffer_t gdk_pixbuf_create_render_buffer( uint32_t width, uint32_t height )
    91 {
    92     render_buffer_t buf = g_malloc0(sizeof(struct render_buffer));
    93     gboolean alpha = FALSE;
    94     buf->width = width;
    95     buf->height = height;
    96     buf->buf_id = video_gdk_find_free();
    97     pixbuf_array[buf->buf_id] = g_malloc0( width * height * 4 );
    98     return buf;
    99 }
   101 static void gdk_pixbuf_destroy_render_buffer( render_buffer_t buffer )
   102 {
   103     g_free(pixbuf_array[buffer->buf_id] );
   104     pixbuf_array[buffer->buf_id] = NULL;
   105     if( buffer->buf_id == (pixbuf_max-1) ) {
   106         pixbuf_max--;
   107     }
   108 }
   110 static void gdk_pixbuf_display_render_buffer( render_buffer_t buffer )
   111 {
   112     glFinish();
   114     void *pb = pixbuf_array[buffer->buf_id];
   115     GdkGC *gc = gtk_video_drawable->style->fg_gc[GTK_STATE_NORMAL];
   116     GdkColor black = {0,0,0,0};
   118     assert(gc);
   120     int x1=0,y1=0,x2=video_width,y2=video_height;
   122     int ah = video_width * 0.75;
   125     if( ah > video_height ) {
   126         int w = (video_height/0.75);
   127         x1 = (video_width - w)/2;
   128         x2 -= x1;
   129         gdk_gc_set_foreground( gc, &black );
   130         gdk_gc_set_background( gc, &black );
   131         gdk_draw_rectangle( gtk_video_drawable->window, gc, TRUE, 0, 0, x1, video_height );
   132         gdk_draw_rectangle( gtk_video_drawable->window, gc, TRUE, x2, 0, video_width, video_height );
   133     } else if( ah < video_height ) {
   134         y1 = (video_height - ah)/2;
   135         y2 -= y1;
   136         gdk_gc_set_foreground( gc, &black );
   137         gdk_gc_set_background( gc, &black );
   138         gdk_draw_rectangle( gtk_video_drawable->window, gc, TRUE, 0, 0, video_width, y1 );
   139         gdk_draw_rectangle( gtk_video_drawable->window, gc, TRUE, 0, y2, video_width, video_height );
   140     }
   141     int w = x2-x1;
   142     int h = y2-y1;
   144     if( w != buffer->width || h != buffer->height ) {
   145         gdk_draw_rgb_32_image( gtk_video_drawable->window, gc, x1, y1, buffer->width, buffer->height, GDK_RGB_DITHER_NONE,
   146                 pb, buffer->width*4 );
   147     } else {
   148         gdk_draw_rgb_32_image( gtk_video_drawable->window, gc, x1, y1, buffer->width, buffer->height, GDK_RGB_DITHER_NONE,
   149                 pb, buffer->width*4 );
   150     }
   151 }
   153 static void gdk_pixbuf_display_blank( uint32_t colour )
   154 {
   155     GdkGC *gc = gtk_video_drawable->style->fg_gc[GTK_STATE_NORMAL];
   156     GdkColor col = { };
   158     gdk_gc_set_foreground( gc, &col );
   159     gdk_gc_set_background( gc, &col );
   160     gdk_draw_rectangle( gtk_video_drawable->window, gc, TRUE, 0, 0, video_width, video_height );
   161 }
   163 static gboolean gdk_pixbuf_set_render_target( render_buffer_t buffer )
   164 {
   165     glFinish();
   166     void *pb = pixbuf_array[buffer->buf_id];
   167     OSMesaMakeCurrent( osmesa_context, pb, GL_UNSIGNED_BYTE,
   168                        buffer->width, buffer->height );
   169     //OSMesaPixelStore( OSMESA_Y_UP, 0 );
   170     glViewport( 0, 0, buffer->width, buffer->height );
   171     glDrawBuffer(GL_FRONT);
   172     return TRUE;
   173 }
   175 static void gdk_pixbuf_load_frame_buffer( frame_buffer_t frame, render_buffer_t buffer )
   176 {
   177     glFinish();
   178     void *pb = pixbuf_array[buffer->buf_id];
   179     OSMesaMakeCurrent( osmesa_context, pb, GL_UNSIGNED_BYTE,
   180                        buffer->width, buffer->height );
   181     GLenum type = colour_formats[frame->colour_format].type;
   182     GLenum format = colour_formats[frame->colour_format].format;
   183     int bpp = colour_formats[frame->colour_format].bpp;
   184     int rowstride = (frame->rowstride / bpp) - frame->width;
   186     gl_reset_state();
   187     glPixelStorei( GL_UNPACK_ROW_LENGTH, rowstride );
   188     glRasterPos2f(0.375, frame->height-0.375);
   189     glPixelZoom( 1.0, 1.0 );
   190     glDrawPixels( frame->width, frame->height, format, type, frame->data );
   191     glFlush();
   192 }
   194 static gboolean gdk_pixbuf_read_render_buffer( unsigned char *target, render_buffer_t buffer, int rowstride, int format )
   195 {
   196     glFinish();
   197     void *pb = pixbuf_array[buffer->buf_id];
   198     OSMesaMakeCurrent( osmesa_context, pb, GL_UNSIGNED_BYTE,
   199                        buffer->width, buffer->height );
   200     glReadBuffer( GL_FRONT );
   201     return gl_read_render_buffer( target, buffer, rowstride, format );
   203 }
.