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 805:b355f7b3ff2e
prev771:749f0f4575d2
next1065:bc1cc0c54917
author nkeynes
date Sat Feb 28 06:26:48 2009 +0000 (15 years ago)
permissions -rw-r--r--
last change Add SDL audio driver, thanks to Wahrhaft!
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  */
    20 #include <gdk/gdkkeysyms.h>
    21 #include <stdint.h>
    22 #include <stdlib.h>
    23 #include "lxdream.h"
    24 #include "display.h"
    25 #include "dckeysyms.h"
    26 #include "drivers/video_gl.h"
    27 #include "drivers/joy_linux.h"
    28 #include "pvr2/pvr2.h"
    29 #include "gtkui/gtkui.h"
    31 #ifdef HAVE_GTK_X11
    33 #include <gdk/gdkx.h>
    34 #include "drivers/video_glx.h"
    36 /************* X11-specificness **********/
    38 guint gdk_keycode_to_modifier( GdkDisplay *display, guint keycode )
    39 {
    40     int i;
    41     int result = 0;
    42     Display *xdisplay = GDK_DISPLAY_XDISPLAY (display);
    43     XModifierKeymap *keymap = XGetModifierMapping( xdisplay );
    44     for( i=0; i<8*keymap->max_keypermod; i++ ) {
    45         if( keymap->modifiermap[i] == keycode ) {
    46             result = 1 << (i/keymap->max_keypermod);
    47             break;
    48         }
    49     }
    50     XFreeModifiermap(keymap);
    51     return result;
    52 }
    54 #if !(GTK_CHECK_VERSION(2,8,0))
    55 /* gdk_display_warp_pointer was added in GTK 2.8. If we're using an earlier
    56  * version, include the code here. (Can't just set the dependency on 2.8 as
    57  * it still hasn't been included in fink yet...) Original copyright statement
    58  * below.
    59  */
    61 /* GDK - The GIMP Drawing Kit
    62  * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
    63  *
    64  * This library is free software; you can redistribute it and/or
    65  * modify it under the terms of the GNU Lesser General Public
    66  * License as published by the Free Software Foundation; either
    67  * version 2 of the License, or (at your option) any later version.
    68  *
    69  * This library is distributed in the hope that it will be useful,
    70  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    71  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    72  * Lesser General Public License for more details.
    73  *
    74  * You should have received a copy of the GNU Lesser General Public
    75  * License along with this library; if not, write to the
    76  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    77  * Boston, MA 02111-1307, USA.
    78  */
    80 /*
    81  * Modified by the GTK+ Team and others 1997-2000.  See the AUTHORS
    82  * file for a list of people on the GTK+ Team.  See the ChangeLog
    83  * files for a list of changes.  These files are distributed with
    84  * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
    85  */
    86 void gdk_display_warp_pointer (GdkDisplay *display,
    87                                GdkScreen  *screen,
    88                                gint        x,
    89                                gint        y)
    90 {
    91     Display *xdisplay;
    92     Window dest;
    94     xdisplay = GDK_DISPLAY_XDISPLAY (display);
    95     dest = GDK_WINDOW_XWINDOW (gdk_screen_get_root_window (screen));
    97     XWarpPointer (xdisplay, None, dest, 0, 0, 0, 0, x, y);  
    98 }
   100 #endif
   102 #endif
   104 #ifdef HAVE_GTK_OSX
   105 #include "drivers/video_nsgl.h"
   107 // Include this prototype as some systems don't have gdkquartz.h installed
   108 NSView  *gdk_quartz_window_get_nsview( GdkWindow *window);
   110 guint gdk_keycode_to_modifier( GdkDisplay *display, guint keycode )
   111 {
   112     return 0;
   113 }
   115 #endif
   119 GtkWidget *gtk_video_drawable = NULL;
   120 int video_width = 640;
   121 int video_height = 480;
   123 gboolean video_gtk_init();
   124 void video_gtk_shutdown();
   125 void video_gtk_display_blank( uint32_t colour );
   126 static uint16_t video_gtk_resolve_keysym( const gchar *keysym );
   127 static uint16_t video_gtk_keycode_to_dckeysym(uint16_t keycode);
   128 static gchar *video_gtk_keycode_to_keysym(uint16_t keycode);
   130 struct display_driver display_gtk_driver = { 
   131         "gtk",
   132         N_("GTK-based OpenGL driver"),
   133         video_gtk_init, 
   134         video_gtk_shutdown,
   135         video_gtk_resolve_keysym,
   136         video_gtk_keycode_to_dckeysym,
   137         video_gtk_keycode_to_keysym,
   138         NULL, NULL, NULL, NULL, NULL, NULL, 
   139         video_gtk_display_blank, NULL };
   141 gboolean video_gtk_expose_callback(GtkWidget *widget, GdkEventExpose *event, gpointer data )
   142 {
   143     pvr2_redraw_display();
   144     return TRUE;
   145 }
   147 gboolean video_gtk_resize_callback(GtkWidget *widget, GdkEventConfigure *event, gpointer data )
   148 {
   149     video_width = event->width;
   150     video_height = event->height;
   151     pvr2_redraw_display();
   152     return TRUE;
   153 }
   155 static uint16_t video_gtk_resolve_keysym( const gchar *keysym )
   156 {
   157     int val = gdk_keyval_from_name( keysym );
   158     if( val == GDK_VoidSymbol )
   159         return 0;
   160     return (uint16_t)val;
   161 }
   163 static gchar *video_gtk_keycode_to_keysym( uint16_t keycode )
   164 {
   165     return g_strdup(gdk_keyval_name(keycode));
   166 }
   168 static uint16_t video_gtk_keycode_to_dckeysym(uint16_t keycode)
   169 {
   170     if( keycode >= 'a' && keycode <= 'z' ) {
   171         return (keycode - 'a') + DCKB_a;
   172     } else if( keycode >= '1' && keycode <= '9' ) {
   173         return (keycode - '1') + DCKB_1;
   174     }
   175     switch(keycode) {
   176     case GDK_0:         return DCKB_0;
   177     case GDK_Return:    return DCKB_Return;
   178     case GDK_Escape:    return DCKB_Escape;
   179     case GDK_BackSpace: return DCKB_BackSpace;
   180     case GDK_Tab:       return DCKB_Tab;
   181     case GDK_space:     return DCKB_space;
   182     case GDK_minus:     return DCKB_minus;
   183     case GDK_equal:     return DCKB_equal;
   184     case GDK_bracketleft: return DCKB_bracketleft;
   185     case GDK_bracketright: return DCKB_bracketright;
   186     case GDK_semicolon: return DCKB_semicolon;
   187     case GDK_apostrophe:return DCKB_apostrophe;
   188     case GDK_grave : return DCKB_grave;
   189     case GDK_comma:     return DCKB_comma;
   190     case GDK_period:    return DCKB_period;
   191     case GDK_slash:     return DCKB_slash; 
   192     case GDK_Caps_Lock: return DCKB_Caps_Lock;
   193     case GDK_F1:        return DCKB_F1;
   194     case GDK_F2:        return DCKB_F2;
   195     case GDK_F3:        return DCKB_F3;
   196     case GDK_F4:        return DCKB_F4;
   197     case GDK_F5:        return DCKB_F5;
   198     case GDK_F6:        return DCKB_F6;
   199     case GDK_F7:        return DCKB_F7;
   200     case GDK_F8:        return DCKB_F8;
   201     case GDK_F9:        return DCKB_F9;
   202     case GDK_F10:       return DCKB_F10;
   203     case GDK_F11:       return DCKB_F11;
   204     case GDK_F12:       return DCKB_F12;
   205     case GDK_Scroll_Lock: return DCKB_Scroll_Lock;
   206     case GDK_Pause:     return DCKB_Pause;
   207     case GDK_Insert:    return DCKB_Insert;
   208     case GDK_Home:      return DCKB_Home;
   209     case GDK_Page_Up:   return DCKB_Page_Up;
   210     case GDK_Delete:    return DCKB_Delete;
   211     case GDK_End:       return DCKB_End;
   212     case GDK_Page_Down: return DCKB_Page_Down;
   213     case GDK_Right:     return DCKB_Right;
   214     case GDK_Left:      return DCKB_Left;
   215     case GDK_Down:      return DCKB_Down;
   216     case GDK_Up:        return DCKB_Up;
   217     case GDK_Num_Lock:  return DCKB_Num_Lock;
   218     case GDK_KP_Divide: return DCKB_KP_Divide;
   219     case GDK_KP_Multiply: return DCKB_KP_Multiply;
   220     case GDK_KP_Subtract: return DCKB_KP_Subtract;
   221     case GDK_KP_Add:    return DCKB_KP_Add;
   222     case GDK_KP_Enter:  return DCKB_KP_Enter;
   223     case GDK_KP_End:    return DCKB_KP_End;
   224     case GDK_KP_Down:   return DCKB_KP_Down;
   225     case GDK_KP_Page_Down: return DCKB_KP_Page_Down;
   226     case GDK_KP_Left:   return DCKB_KP_Left;
   227     case GDK_KP_Begin:  return DCKB_KP_Begin;
   228     case GDK_KP_Right:  return DCKB_KP_Right;
   229     case GDK_KP_Home:   return DCKB_KP_Home;
   230     case GDK_KP_Up:     return DCKB_KP_Up;
   231     case GDK_KP_Page_Up:return DCKB_KP_Page_Up;
   232     case GDK_KP_Insert: return DCKB_KP_Insert;
   233     case GDK_KP_Delete: return DCKB_KP_Delete;
   234     case GDK_backslash: return DCKB_backslash;
   235     case GDK_Control_L: return DCKB_Control_L;
   236     case GDK_Shift_L:   return DCKB_Shift_L;
   237     case GDK_Alt_L:     return DCKB_Alt_L;
   238     case GDK_Meta_L:    return DCKB_Meta_L;
   239     case GDK_Control_R: return DCKB_Control_R;
   240     case GDK_Shift_R:   return DCKB_Shift_R;
   241     case GDK_Alt_R:     return DCKB_Alt_R;
   242     case GDK_Meta_R:    return DCKB_Meta_R;
   243     }
   244     return DCKB_NONE;
   245 }
   247 GtkWidget *video_gtk_create_drawable()
   248 {
   249     GtkWidget *drawable = gtk_drawing_area_new();
   250     GTK_WIDGET_SET_FLAGS(drawable, GTK_CAN_FOCUS|GTK_CAN_DEFAULT);
   252     g_signal_connect( drawable, "expose_event",
   253                       G_CALLBACK(video_gtk_expose_callback), NULL );
   254     g_signal_connect( drawable, "configure_event",
   255                       G_CALLBACK(video_gtk_resize_callback), NULL );
   257 #ifdef HAVE_GLX
   258     Display *display = gdk_x11_display_get_xdisplay( gtk_widget_get_display(drawable));
   259     Screen *screen = gdk_x11_screen_get_xscreen( gtk_widget_get_screen(drawable));
   260     int screen_no = XScreenNumberOfScreen(screen);
   261     if( !video_glx_init(display, screen_no) ) {
   262         ERROR( "Unable to initialize GLX, aborting" );
   263         exit(3);
   264     }
   266     XVisualInfo *visual = video_glx_get_visual();
   267     if( visual != NULL ) {
   268         GdkVisual *gdkvis = gdk_x11_screen_lookup_visual( gtk_widget_get_screen(drawable), visual->visualid );
   269         GdkColormap *colormap = gdk_colormap_new( gdkvis, FALSE );
   270         gtk_widget_set_colormap( drawable, colormap );
   271     }
   272 #endif
   273     gtk_video_drawable = drawable;
   274     return drawable;
   275 }
   277 gboolean video_gtk_init()
   278 {
   280     if( gtk_video_drawable == NULL ) {
   281         return FALSE;
   282     }
   284     video_width = gtk_video_drawable->allocation.width;
   285     video_height = gtk_video_drawable->allocation.height;
   286 #ifdef HAVE_OSMESA
   287     video_gdk_init_driver( &display_gtk_driver );
   288 #else
   289 #ifdef HAVE_GLX
   290     Display *display = gdk_x11_display_get_xdisplay( gtk_widget_get_display(GTK_WIDGET(gtk_video_drawable)));
   291     Window window = GDK_WINDOW_XWINDOW( GTK_WIDGET(gtk_video_drawable)->window );
   292     if( ! video_glx_init_context( display, window ) ||
   293             ! video_glx_init_driver( &display_gtk_driver ) ) {
   294         return FALSE;
   295     }
   296 #else
   297 #ifdef HAVE_NSGL
   298     NSView *view = gdk_quartz_window_get_nsview(gtk_video_drawable->window);
   299     if( ! video_nsgl_init_driver( view, &display_gtk_driver ) ) {
   300         return FALSE;
   301     }
   302 #endif
   303 #endif
   304 #endif
   306     pvr2_setup_gl_context();
   308 #ifdef HAVE_LINUX_JOYSTICK
   309     linux_joystick_init();
   310 #endif
   311     return TRUE;
   312 }
   314 void video_gtk_display_blank( uint32_t colour )
   315 {
   316     GdkGC *gc = gdk_gc_new(gtk_video_drawable->window);
   317     GdkColor color = {0, ((colour>>16)&0xFF)*257, ((colour>>8)&0xFF)*257, ((colour)&0xFF)*257 };
   318     GdkColormap *cmap = gdk_colormap_get_system();
   319     gdk_colormap_alloc_color( cmap, &color, TRUE, TRUE );
   320     gdk_gc_set_foreground( gc, &color );
   321     gdk_gc_set_background( gc, &color );
   322     gdk_draw_rectangle( gtk_video_drawable->window, gc, TRUE, 0, 0, video_width, video_height );
   323     gdk_gc_destroy(gc);
   324     gdk_colormap_free_colors( cmap, &color, 1 );
   325 }
   327 void video_gtk_shutdown()
   328 {
   329     if( gtk_video_drawable != NULL ) {
   330 #ifdef HAVE_OSMESA
   331         video_gdk_shutdown();
   332 #else
   333 #ifdef HAVE_GLX
   334         video_glx_shutdown();
   335 #else
   336 #ifdef HAVE_NSGL
   337         video_nsgl_shutdown();
   338 #endif
   339 #endif
   340 #endif
   341     }
   342 #ifdef HAVE_LINUX_JOYSTICK
   343     linux_joystick_shutdown();
   344 #endif
   345 }
.