filename | src/drivers/video_gtk.c |
changeset | 805:b355f7b3ff2e |
prev | 771:749f0f4575d2 |
next | 1065:bc1cc0c54917 |
author | nkeynes |
date | Wed Mar 25 11:57:05 2009 +0000 (15 years ago) |
permissions | -rw-r--r-- |
last change | Change glXMakeContextCurrent call to glXMakeCurrent - works around crash bug in mesa: http://www.mail-archive.com/mesa-commit@lists.freedesktop.org/msg04338.html |
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 }
.