nkeynes@94: /** nkeynes@586: * $Id$ nkeynes@94: * nkeynes@94: * The PC side of the video support (responsible for actually displaying / nkeynes@94: * rendering frames) nkeynes@94: * nkeynes@94: * Copyright (c) 2005 Nathan Keynes. nkeynes@94: * nkeynes@94: * This program is free software; you can redistribute it and/or modify nkeynes@94: * it under the terms of the GNU General Public License as published by nkeynes@94: * the Free Software Foundation; either version 2 of the License, or nkeynes@94: * (at your option) any later version. nkeynes@94: * nkeynes@94: * This program is distributed in the hope that it will be useful, nkeynes@94: * but WITHOUT ANY WARRANTY; without even the implied warranty of nkeynes@94: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the nkeynes@94: * GNU General Public License for more details. nkeynes@94: */ nkeynes@94: nkeynes@94: #include nkeynes@485: #include nkeynes@94: #include nkeynes@180: #include "dream.h" nkeynes@144: #include "display.h" nkeynes@608: #include "dckeysyms.h" nkeynes@545: #include "drivers/video_glx.h" nkeynes@653: #include "drivers/video_gl.h" nkeynes@586: #include "pvr2/pvr2.h" nkeynes@537: #include "gtkui/gtkui.h" nkeynes@94: nkeynes@653: GtkWidget *gtk_video_win = NULL; nkeynes@436: int video_width = 640; nkeynes@436: int video_height = 480; nkeynes@94: nkeynes@352: gboolean video_gtk_init(); nkeynes@352: void video_gtk_shutdown(); nkeynes@552: gboolean video_gtk_display_blank( uint32_t colour ); nkeynes@144: uint16_t video_gtk_resolve_keysym( const gchar *keysym ); nkeynes@614: uint16_t video_gtk_keycode_to_dckeysym(uint16_t keycode); nkeynes@94: nkeynes@370: struct display_driver display_gtk_driver = { "gtk", video_gtk_init, video_gtk_shutdown, nkeynes@352: video_gtk_resolve_keysym, nkeynes@608: video_gtk_keycode_to_dckeysym, nkeynes@614: NULL, nkeynes@552: NULL, NULL, NULL, NULL, NULL, nkeynes@552: video_gtk_display_blank, NULL }; nkeynes@449: nkeynes@144: uint16_t video_gtk_resolve_keysym( const gchar *keysym ) nkeynes@144: { nkeynes@144: int val = gdk_keyval_from_name( keysym ); nkeynes@144: if( val == GDK_VoidSymbol ) nkeynes@144: return 0; nkeynes@144: return (uint16_t)val; nkeynes@144: } nkeynes@144: nkeynes@435: gboolean video_gtk_expose_callback(GtkWidget *widget, GdkEventExpose *event, gpointer data ) nkeynes@435: { nkeynes@545: render_buffer_t buffer = pvr2_get_front_buffer(); nkeynes@545: if( buffer == NULL ) { nkeynes@545: display_gtk_driver.display_blank(pvr2_get_border_colour()); nkeynes@545: } else { nkeynes@545: display_gtk_driver.display_render_buffer(buffer); nkeynes@545: } nkeynes@443: return TRUE; nkeynes@435: } nkeynes@435: nkeynes@436: gboolean video_gtk_resize_callback(GtkWidget *widget, GdkEventConfigure *event, gpointer data ) nkeynes@436: { nkeynes@436: video_width = event->width; nkeynes@436: video_height = event->height; nkeynes@545: video_gtk_expose_callback(widget, NULL, data); nkeynes@443: return TRUE; nkeynes@436: } nkeynes@436: nkeynes@614: uint16_t video_gtk_keycode_to_dckeysym(uint16_t keycode) nkeynes@608: { nkeynes@608: if( keycode >= 'a' && keycode <= 'z' ) { nkeynes@608: return (keycode - 'a') + DCKB_A; nkeynes@608: } else if( keycode >= '1' && keycode <= '9' ) { nkeynes@608: return (keycode - '1') + DCKB_1; nkeynes@608: } nkeynes@608: switch(keycode) { nkeynes@609: case GDK_0: return DCKB_0; nkeynes@609: case GDK_Return: return DCKB_ENTER; nkeynes@609: case GDK_Escape: return DCKB_ESCAPE; nkeynes@609: case GDK_BackSpace: return DCKB_BACKSPACE; nkeynes@609: case GDK_Tab: return DCKB_TAB; nkeynes@609: case GDK_space: return DCKB_SPACE; nkeynes@609: case GDK_minus: return DCKB_MINUS; nkeynes@609: case GDK_equal: return DCKB_EQUAL; nkeynes@609: case GDK_bracketleft: return DCKB_LBRACKET; nkeynes@609: case GDK_bracketright: return DCKB_RBRACKET; nkeynes@609: case GDK_semicolon: return DCKB_SEMICOLON; nkeynes@609: case GDK_apostrophe:return DCKB_QUOTE; nkeynes@609: case GDK_grave : return DCKB_BACKQUOTE; nkeynes@609: case GDK_comma: return DCKB_COMMA; nkeynes@609: case GDK_period: return DCKB_PERIOD; nkeynes@609: case GDK_slash: return DCKB_SLASH; nkeynes@609: case GDK_Caps_Lock: return DCKB_CAPSLOCK; nkeynes@609: case GDK_F1: return DCKB_F1; nkeynes@609: case GDK_F2: return DCKB_F2; nkeynes@609: case GDK_F3: return DCKB_F3; nkeynes@609: case GDK_F4: return DCKB_F4; nkeynes@609: case GDK_F5: return DCKB_F5; nkeynes@609: case GDK_F6: return DCKB_F6; nkeynes@609: case GDK_F7: return DCKB_F7; nkeynes@609: case GDK_F8: return DCKB_F8; nkeynes@609: case GDK_F9: return DCKB_F9; nkeynes@609: case GDK_F10: return DCKB_F10; nkeynes@609: case GDK_F11: return DCKB_F11; nkeynes@609: case GDK_F12: return DCKB_F12; nkeynes@609: case GDK_Scroll_Lock: return DCKB_SCROLLLOCK; nkeynes@609: case GDK_Pause: return DCKB_PAUSE; nkeynes@609: case GDK_Insert: return DCKB_INSERT; nkeynes@609: case GDK_Home: return DCKB_HOME; nkeynes@609: case GDK_Page_Up: return DCKB_PAGEUP; nkeynes@609: case GDK_Delete: return DCKB_DELETE; nkeynes@609: case GDK_End: return DCKB_END; nkeynes@609: case GDK_Page_Down: return DCKB_PAGEDOWN; nkeynes@609: case GDK_Right: return DCKB_RIGHT; nkeynes@609: case GDK_Left: return DCKB_LEFT; nkeynes@609: case GDK_Down: return DCKB_DOWN; nkeynes@609: case GDK_Up: return DCKB_UP; nkeynes@609: case GDK_Num_Lock: return DCKB_NUMLOCK; nkeynes@609: case GDK_KP_Divide: return DCKB_KP_SLASH; nkeynes@609: case GDK_KP_Multiply: return DCKB_KP_STAR; nkeynes@609: case GDK_KP_Subtract: return DCKB_KP_MINUS; nkeynes@609: case GDK_KP_Add: return DCKB_KP_PLUS; nkeynes@609: case GDK_KP_Enter: return DCKB_KP_ENTER; nkeynes@631: case GDK_KP_End: return DCKB_KP_1; nkeynes@631: case GDK_KP_Down: return DCKB_KP_2; nkeynes@631: case GDK_KP_Page_Down: return DCKB_KP_3; nkeynes@631: case GDK_KP_Left: return DCKB_KP_4; nkeynes@631: case GDK_KP_Begin: return DCKB_KP_5; nkeynes@631: case GDK_KP_Right: return DCKB_KP_6; nkeynes@631: case GDK_KP_Home: return DCKB_KP_7; nkeynes@631: case GDK_KP_Up: return DCKB_KP_8; nkeynes@631: case GDK_KP_Page_Up:return DCKB_KP_9; nkeynes@631: case GDK_KP_Insert: return DCKB_KP_0; nkeynes@632: case GDK_KP_Delete: return DCKB_KP_PERIOD; nkeynes@609: case GDK_backslash: return DCKB_BACKSLASH; nkeynes@609: case GDK_Control_L: return DCKB_CONTROL_L; nkeynes@609: case GDK_Shift_L: return DCKB_SHIFT_L; nkeynes@609: case GDK_Alt_L: return DCKB_ALT_L; nkeynes@609: case GDK_Meta_L: return DCKB_S1; nkeynes@609: case GDK_Control_R: return DCKB_CONTROL_R; nkeynes@609: case GDK_Shift_R: return DCKB_SHIFT_R; nkeynes@609: case GDK_Alt_R: return DCKB_ALT_R; nkeynes@609: case GDK_Meta_R: return DCKB_S2; nkeynes@608: } nkeynes@608: return DCKB_NONE; nkeynes@608: } nkeynes@608: nkeynes@352: gboolean video_gtk_init() nkeynes@94: { nkeynes@545: nkeynes@653: gtk_video_win = gtk_gui_get_renderarea(); nkeynes@653: if( gtk_video_win == NULL ) { nkeynes@530: return FALSE; nkeynes@530: } nkeynes@435: nkeynes@653: g_signal_connect( gtk_video_win, "expose_event", nkeynes@435: G_CALLBACK(video_gtk_expose_callback), NULL ); nkeynes@653: g_signal_connect( gtk_video_win, "configure_event", nkeynes@436: G_CALLBACK(video_gtk_resize_callback), NULL ); nkeynes@653: video_width = gtk_video_win->allocation.width; nkeynes@653: video_height = gtk_video_win->allocation.height; nkeynes@653: Display *display = gdk_x11_display_get_xdisplay( gtk_widget_get_display(GTK_WIDGET(gtk_video_win))); nkeynes@653: Window window = GDK_WINDOW_XWINDOW( GTK_WIDGET(gtk_video_win)->window ); nkeynes@653: #ifdef HAVE_LIBOSMESA nkeynes@653: video_gdk_init_driver( &display_gtk_driver ); nkeynes@653: #else nkeynes@552: if( ! video_glx_init_context( display, window ) || nkeynes@552: ! video_glx_init_driver( &display_gtk_driver ) ) { nkeynes@552: return FALSE; nkeynes@552: } nkeynes@653: #endif nkeynes@653: nkeynes@614: #ifdef HAVE_LINUX_JOYSTICK nkeynes@614: linux_joystick_init(); nkeynes@614: #endif nkeynes@552: return TRUE; nkeynes@552: } nkeynes@552: nkeynes@552: gboolean video_gtk_display_blank( uint32_t colour ) nkeynes@552: { nkeynes@653: GdkGC *gc = gdk_gc_new(gtk_video_win->window); nkeynes@552: GdkColor color = {0, ((colour>>16)&0xFF)*257, ((colour>>8)&0xFF)*257, ((colour)&0xFF)*257 }; nkeynes@552: GdkColormap *cmap = gdk_colormap_get_system(); nkeynes@552: gdk_colormap_alloc_color( cmap, &color, TRUE, TRUE ); nkeynes@552: gdk_gc_set_foreground( gc, &color ); nkeynes@552: gdk_gc_set_background( gc, &color ); nkeynes@653: gdk_draw_rectangle( gtk_video_win->window, gc, TRUE, 0, 0, video_width, video_height ); nkeynes@552: gdk_gc_destroy(gc); nkeynes@552: gdk_colormap_free_colors( cmap, &color, 1 ); nkeynes@94: } nkeynes@94: nkeynes@653: XVisualInfo *video_gtk_get_visual() nkeynes@653: { nkeynes@653: #ifdef HAVE_LIBOSMESA nkeynes@653: return NULL; nkeynes@653: #else nkeynes@653: return video_glx_get_visual(); nkeynes@653: #endif nkeynes@653: } nkeynes@653: nkeynes@352: void video_gtk_shutdown() nkeynes@352: { nkeynes@653: if( gtk_video_win != NULL ) { nkeynes@653: #ifdef HAVE_LIBOSMESA nkeynes@653: video_gdk_shutdown(); nkeynes@653: #else nkeynes@530: video_glx_shutdown(); nkeynes@653: #endif nkeynes@530: } nkeynes@620: #ifdef HAVE_LINUX_JOYSTICK nkeynes@620: linux_joystick_shutdown(); nkeynes@620: #endif nkeynes@94: } nkeynes@94: