sinek/src gtkxine.c,1.5,1.6

[email protected] Tue, 14 Jan 2003 02:44:27 -0800
Newsgroups gmane.comp.video.sinek.cvs
Message-ID <[email protected]>
Update of /cvsroot/sinek/sinek/src
In directory sc8-pr-cvs1:/tmp/cvs-serv28995/src

Modified Files:
	gtkxine.c 
Log Message:
yikes, what a pain in the ass.  anyways, it now displays video at the correct framerate.


Index: gtkxine.c
===================================================================
RCS file: /cvsroot/sinek/sinek/src/gtkxine.c,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -d -r1.5 -r1.6
--- gtkxine.c	6 Jan 2003 06:54:14 -0000	1.5
+++ gtkxine.c	14 Jan 2003 10:44:24 -0000	1.6
@@ -10,9 +10,9 @@
 
 #include "gtkxine.h"
 #include <gtk/gtk.h>
-#include <gdk/gdkx.h>
 #include <xine.h>
 #include <math.h>
+#include <string.h>
 #include <libintl.h>
 
 #ifdef HAVE_CONFIG_H
@@ -21,6 +21,18 @@
 
 #define _(x) (x)
 
+struct _GtkXineVideoInfo
+{
+	/* finalize video subsystem */
+	void (*video_exit) (GtkXine *);
+	/* handle visual-specific events (ie, X11 XEvents and win32 MSGs) */
+	GdkFilterReturn (*event_filter) (GdkXEvent *, GdkEvent *, gpointer);
+	/* XINE_VISUAL_TYPE_? */
+	int visual_type;
+	/* arg supplied to xine_open_video_driver */
+	void *visual_data;
+};
+
 struct _GtkXine
 {
 	GtkWidget parent;
@@ -29,28 +41,16 @@
 	int conf_loaded;
 	xine_audio_port_t *ao_driver;
 	xine_video_port_t *vo_driver;
-	xine_stream_t *stream;
 
-	void (*warning_cb) (const char *msg);
-	void (*error_cb) (const char *msg);
+	xine_stream_t *stream;
 
 	char *current_mrl;
 	int x, y, w, h;
+	GdkDrawable *window;
 
-	/* x11 specific stuff */
-	// char *display_name;
+	struct _GtkXineVideoInfo info;
 };
 
-static void default_warning_cb (const char *msg)
-{
-	g_warning ("%s\n", msg);
-}
-
-static void default_error_cb (const char *msg)
-{
-	g_error ("%s\n", msg);
-}
-
 static void gtk_xine_init (GtkXine *xine)
 {
 	xine->xine = xine_new ();
@@ -59,276 +59,23 @@
 	xine->vo_driver = NULL;
 	xine->stream = NULL;
 
-	xine->warning_cb = default_warning_cb;
-	xine->error_cb = default_error_cb;
-
 	xine->current_mrl = NULL;
 	xine->x = xine->y = xine->w = xine->h = 0;
+	xine->window = NULL;
 
-	/*
-	xine->video_win_title = g_strdup ("Xine Video Output");
-	xine->display_name = NULL;
-	*/
-
-	/* XXX: is this correct? */
-	gtk_set_locale ();
-	/* xine_set_locale (); */
-	bindtextdomain (PACKAGE, XINE_LOCALEDIR);
-	bind_textdomain_codeset (PACKAGE, "UTF-8");
-	textdomain (PACKAGE);
-
-}
-
-#if 0
-static void gtk_xine_build_audio_out (GtkXine *xine)
-{
-	char *id, **driver_ids;
-	int i;
-
-	id = xine->conf->register_string (xine->conf, "audio.driver", "auto", "audio driver to use", NULL, NULL, NULL);
-	if (xine->audio_driver)
-		id = xine->audio_driver;
-
-	if (strcmp (id, "null") != 0) {
-		if (strcmp (id, "auto") != 0)
-			xine->ao_driver = xine_load_audio_output_plugin (xine->conf, id);
-		
-		/* try guessing, if no audio driver is loaded at this point */
-		if (xine->ao_driver == NULL) {
-			driver_ids = xine_list_audio_output_plugins ();
-
-			for (i = 0; xine->ao_driver == NULL && driver_ids[i] != NULL; i++) {
-				xine->ao_driver = xine_load_audio_output_plugin (xine->conf, driver_ids[i]);
-			}
-			g_strfreev (driver_ids);	
-		}
-	}
-
-	if (xine->ao_driver == NULL)
-		id = "null";
-	xine->conf->update_string (xine->conf, "audio.driver", id);
-}
-
-#if 0
-static int video_window_expose_event_cb (GtkWidget *w, GtkXine *xine)
-{
-	g_print ("%s()\n", __FUNCTION__);
-	gdk_draw_arc (w->window, w->style->fg_gc[GTK_WIDGET_STATE (w)], TRUE,
-		0, 0, w->allocation.width, w->allocation.height, 0, 64 * 360);
-	return TRUE;
-}
-#endif
-
-#if 0
-static void gtk_xine_frame_output_cb (GtkXine *xine, int vid_w, int vid_h, int *dest_x, int *dest_y, int *dest_w, int *dest_h, int *win_x, int *win_y)
-{
-	*dest_x = 0;
-	*dest_y = 0;
-	*dest_w = xine->visual.video_width;
-	*dest_h = xine->visual.video_height;
-	/* TODO: cache x/y in GtkXine struct, update for every move signal */
-	gtk_window_get_position (GTK_WINDOW (xine->video_win), win_x, win_y);
-	g_print ("%s(): x=%d,y=%d,w=%d,h=%d; window x=%d,y=%d\n", __FUNCTION__, *dest_x, *dest_y, *dest_w, *dest_h, *win_x, *win_y);
-}
-
-static void gtk_xine_dest_size_cb (void *widget, int vid_w, int vid_h, int *dest_w, int *dest_h)
-{
-	GtkXine *xine = GTK_XINE (widget);
-
-	*dest_w = xine->visual.video_width;
-	*dest_h = xine->visual.video_height;
-}
-
-static GtkWidget *gtk_xine_build_video_out_window (GtkXine *xine)
-{
-	int horiz, vert;
-	GtkWidget *video_area;
-	x11_visual_t visual;
-
-	xine->visual.video_width = xine->conf->register_num (xine->conf, "video.win_width", 320, "video output window width", NULL, NULL, NULL);
-	xine->visual.video_height = xine->conf->register_num (xine->conf, "video.win_height", 160, "video output window height", NULL, NULL, NULL);
-
-	xine->video_win = gtk_window_new (GTK_WINDOW_TOPLEVEL);
-	gtk_window_set_title (GTK_WINDOW (xine->video_win), xine->video_win_title);
-	gtk_window_set_policy (GTK_WINDOW (xine->video_win), TRUE, TRUE, FALSE);
-	
-	video_area = gtk_drawing_area_new ();
-	gtk_widget_set_size_request (video_area, xine->visual.video_width, xine->visual.video_height);
-	//gtk_widget_modify_bg (video_area, 
-	//g_signal_connect (G_OBJECT (video_area), "expose_event", G_CALLBACK (video_window_expose_event_cb), xine);
-	// TODO: catch resizes!
-	gtk_container_add (GTK_CONTAINER (xine->video_win), video_area);
-
-	gtk_widget_show_all (xine->video_win);
-	//gtk_widget_realize (video_area);
-
-	visual.display = GDK_WINDOW_XDISPLAY (video_area->window);
-	visual.screen = gdk_x11_get_default_screen ();
-	visual.d = GDK_WINDOW_XWINDOW (video_area->window);
-
-	horiz = (DisplayWidth (visual.display, visual.screen) * 1000) / DisplayWidthMM (visual.display, visual.screen);
-	vert = (DisplayHeight (visual.display, visual.screen) * 1000) / DisplayHeightMM (visual.display, visual.screen);
-	visual.display_ratio = horiz / vert;
-	visual.frame_output_cb = gtk_xine_frame_output_cb;
-	visual.dest_size_cb = gtk_xine_dest_size_cb;
-	visual.user_data = (void *) xine;
-	if (fabs (visual.display_ratio - 1.0) < 0.01)
-		visual.display_ratio = 1.0;
-
-	//gtk_main();
-	//sleep(20);
-	//exit(2);
-
-	//return xine->video_win;
-	return visual;
-}
-
-static void gtk_xine_build_video_out (GtkXine *xine)
-{
-	x11_visual_t vis;
-	char *id, **driver_ids;
-	double res_h, res_v;
-	int i;
-
-	id = xine->conf->register_string (xine->conf, "video.driver", "auto", "video driver to use", NULL, NULL, NULL);
-	if (xine->video_driver)
-		id = xine->video_driver;
-
-	if (strcmp (id, "null") != 0) {
-		vis = gtk_xine_build_video_out_window (xine);
-		xine->visual.display = vis.display;
-		xine->visual.screen = vis.screen;
-		xine->visual.display_ratio = vis.display_ratio;
-		xine->visual.d = vis.d;
-		xine->visual.user_data = vis.user_data;
-		xine->visual.dest_size_cb = vis.dest_size_cb;
-		xine->visual.frame_output_cb = vis.frame_output_cb;
-		xine->visual.depth = gdk_drawable_get_depth (GDK_DRAWABLE (xine->video_win->window));
-
-		/* fill in x11_visual_t info */
-#if 0
-if(XShmQueryExtension(di->display) == True)
-	MyShmEvent = XShmGetEventBase(di->display) + ShmCompletion;
-#endif
-#if 0
-		if (xine->display_name) {
-			vis.display = XOpenDisplay (xine->display_name);
-			if (!vis.display)
-				g_error ("Cannot connect to display '%s'.\n", xine->display_name);
-			XLockDisplay (vis.display);
-			vis.screen = DefaultScreen (vis.display);
-		}
-		else {
-			vis.display = XOpenDisplay (gdk_get_display ());
-			XLockDisplay (vis.display);
-			vis.screen = gdk_x11_get_default_screen ();
-		}
-#endif
-	
-		if (strcmp (id, "auto") != 0)
-			xine->vo_driver = xine_load_video_output_plugin (xine->conf, id, VISUAL_TYPE_GTK, (void *) &vis);
-		
-		/* try guessing, if no video driver is loaded at this point */
-		if (xine->vo_driver == NULL) {
-			driver_ids = xine_list_video_output_plugins (VISUAL_TYPE_GTK);
-
-			for (i = 0; xine->vo_driver == NULL && driver_ids[i] != NULL; i++) {
-				xine->vo_driver = xine_load_video_output_plugin (xine->conf, driver_ids[i], VISUAL_TYPE_GTK, (void *) &vis);
-			}
-			g_strfreev (driver_ids);	
-		}
-
-		//XUnlockDisplay (vis.display);
-	}
-
-	if (xine->vo_driver == NULL)
-		id = "null";
-	xine->conf->update_string (xine->conf, "video.driver", id);
-}
-#endif
-
-static void gtk_xine_build_video_out (GtkXine *xine)
-{
-	char *id, **driver_ids;
-	double res_h, res_v;
-	int width, height;
-	GtkWidget *video_area;
-	int i;
-
-	id = xine->conf->register_string (xine->conf, "video.driver", "auto", "video driver to use", NULL, NULL, NULL);
-	if (xine->video_driver)
-		id = xine->video_driver;
-
-	if (strcmp (id, "null") != 0) {
-		/* create video window */
-		width = xine->conf->register_num (xine->conf, "video.win_width", 320, "video output window width", NULL, NULL, NULL);
-		height = xine->conf->register_num (xine->conf, "video.win_height", 160, "video output window height", NULL, NULL, NULL);
-
-		xine->video_win = gtk_window_new (GTK_WINDOW_TOPLEVEL);
-		gtk_window_set_title (GTK_WINDOW (xine->video_win), xine->video_win_title);
-		gtk_window_set_policy (GTK_WINDOW (xine->video_win), FALSE, FALSE, FALSE); /* TODO: allow resizing */
-	
-		video_area = gtk_drawing_area_new ();
-		gtk_widget_set_size_request (video_area, width, height);
-		//g_signal_connect (G_OBJECT (video_area), "expose_event", G_CALLBACK (video_window_expose_event_cb), xine);
-		//g_signal_connect (G_OBJECT (video_area), "configure_event", G_CALLBACK (video_window_configure_event_cb), xine);
-		gtk_container_add (GTK_CONTAINER (xine->video_win), video_area);
-
-		gtk_widget_show_all (xine->video_win);
-		//gtk_widget_realize (video_area);
-
-		//horiz = (DisplayWidth (visual.display, visual.screen) * 1000) / DisplayWidthMM (visual.display, visual.screen);
-		//vert = (DisplayHeight (visual.display, visual.screen) * 1000) / DisplayHeightMM (visual.display, visual.screen);
-		//visual.display_ratio = horiz / vert;
-		//visual.frame_output_cb = gtk_xine_frame_output_cb;
-		//visual.dest_size_cb = gtk_xine_dest_size_cb;
-		//visual.user_data = (void *) xine;
-		//if (fabs (visual.display_ratio - 1.0) < 0.01)
-			//visual.display_ratio = 1.0;
-g_print("%s(): id=%s\n", __FUNCTION__, id);
-
-		if (strcmp (id, "auto") != 0)
-			xine->vo_driver = xine_load_video_output_plugin (xine->conf, id, VISUAL_TYPE_GTK, (void *) video_area);
-		
-		/* try guessing, if no video driver is loaded at this point */
-		if (xine->vo_driver == NULL) {
-			driver_ids = xine_list_video_output_plugins (VISUAL_TYPE_GTK);
-
-			for (i = 0; xine->vo_driver == NULL && driver_ids[i] != NULL; i++) {
-g_print("%s(): trying %s\n", __FUNCTION__, driver_ids[i]);
-				xine->vo_driver = xine_load_video_output_plugin (xine->conf, driver_ids[i], VISUAL_TYPE_GTK, (void *) video_area);
-			}
-			g_strfreev (driver_ids);	
-		}
-
-	}
-
-	if (xine->vo_driver == NULL)
-		id = "null";
-	xine->conf->update_string (xine->conf, "video.driver", id);
-}
-
-static void gtk_xine_build (GtkXine *xine)
-{
-	g_print ("%s()\n", __FUNCTION__);
-
-	xine->conf = xine_config_file_init (xine->conf_file);
-	gtk_xine_build_audio_out (xine);
-	gtk_xine_build_video_out (xine);
-	xine->xine = xine_init (xine->vo_driver, xine->ao_driver, xine->conf);
+	memset ((void *) &xine->info, 0, sizeof (xine->info));
 }
-#endif
 
 static void gtk_xine_dispose (GObject *obj)
 {
 	GtkXine *xine = GTK_XINE (obj);
 	GtkWidgetClass *parent = g_type_class_peek (GTK_TYPE_WIDGET);
 
-	g_print ("%s()\n", __FUNCTION__);
-
-	xine_exit (xine->xine);
+	if (xine->info.video_exit)
+		xine->info.video_exit (xine);
 	if (xine->current_mrl)
 		g_free (xine->current_mrl);
+	xine_exit (xine->xine);
 
 	if (G_OBJECT_CLASS (parent)->dispose)
 		G_OBJECT_CLASS (parent)->dispose (obj);
@@ -337,15 +84,17 @@
 static void gtk_xine_class_init (GtkXineClass *class)
 {
 	GObjectClass *gobj_class = G_OBJECT_CLASS (class);
-	/* GtkWidgetClass *gtkwid_class = GTK_WIDGET_CLASS (class); */
-	g_print ("%s()\n", __FUNCTION__);
+	/*GtkWidgetClass *gtkwid_class = GTK_WIDGET_CLASS (class);*/
 
+	/*
+	gtkwid_class->realize = gtk_xine_realize;
+	gtkwid_class->unrealize = gtk_xine_unrealize;
+	*/
+	
 	/* gobj_class->finalize = gtk_xine_finalize; */
 	gobj_class->dispose = gtk_xine_dispose;
 	/* gobj_class->{set,get}_property = */
 
-
-
 	/* g_object_class_set_property (klass, .... ) */
 }
 
@@ -382,7 +131,7 @@
 int gtk_xine_config_load (GtkXine *xine, const char *conffile)
 {
 	if (xine->conf_loaded) {
-		xine->warning_cb (_("loading over old config file, discarding previous."));
+		g_warning (_("loading over old config file, discarding previous."));
 		xine_config_reset (xine->xine);
 	}
 
@@ -474,7 +223,7 @@
 	return 0;
 }
 
-/* xine setup */
+/* xine audio setup */
 
 const char *gtk_xine_set_audio_driver (GtkXine *xine, const char *name)
 {
@@ -509,98 +258,181 @@
 	return name;
 }
 
+/*
+** Video driver specific stuff.  Each should declare gtk_xine_video_info_init().
+*/
+
+#define GTK_XINE_X11
+#ifdef GTK_XINE_X11
+
+/*
+** X-specific video stuff.
+*/
+
+#include <X11/Xlib.h>
+#include <X11/extensions/XShm.h>
+#include <gdk/gdkx.h>
+
+static int XineCompletionEvent = 0;
+
 static void frame_output_cb (void *user_data, int vid_w, int vid_h, double vidp_aspect, int *dest_x, int *dest_y, int *dest_w, int *dest_h, double *dest_vidp_aspect, int *win_x, int *win_y)
 {
-	GtkXine *xine = GTK_XINE (user_data);
+	GtkXine *xine = (GtkXine *) user_data;
 
 	*dest_w = xine->w;
 	*dest_h = xine->h;
 	*win_x = xine->x;
 	*win_y = xine->y;
 	*dest_x = *dest_y = 0;
-	*dest_vidp_aspect = 1.0;
+	*dest_vidp_aspect = vidp_aspect;
 }
 
 static void dest_size_cb (void *user_data, int vid_w, int vid_h, double vidp_aspect, int *dest_w, int *dest_h, double *dest_vidp_aspect)
 {
-	GtkXine *xine = GTK_XINE (user_data);
+	GtkXine *xine = (GtkXine *) user_data;
 
 	*dest_w = xine->w;
 	*dest_h = xine->h;
-	*dest_vidp_aspect = 1.0;
+	*dest_vidp_aspect = vidp_aspect;
 }
 
-static int get_visual_info (GtkXine *xine, GtkWidget *draw, x11_visual_t *vis)
+static void gtk_xine_x11_video_exit (GtkXine *xine)
 {
-	if (!GTK_IS_DRAWING_AREA (draw)) {
-		xine->error_cb (_("xine video driver expects to be supplied with a GtkDrawingArea widget."));
-		return 0;
-	}
-	if (!gtk_widget_get_parent (draw)) {
-		xine->error_cb (_("xine video driver expects the GtkDrawingArea it gets to have a valid parent window."));
-		return 0;
-	}
-	if (!GTK_WIDGET_VISIBLE (draw)) {
-//		xine->warning_cb (_("xine video driver expects the GtkDrawingArea it gets to be visible; displaying widget."));
-		gtk_widget_realize (draw);
-		gtk_widget_show (draw);
+	g_free (xine->info.visual_data);
+}
+
+static GdkFilterReturn gtk_xine_x11_event_filter (GdkXEvent *xevent, GdkEvent *event, gpointer data)
+{
+	GtkXine *xine = GTK_XINE (data);
+	XEvent *ev = (XEvent *) xevent;
+
+	if (ev->type == XineCompletionEvent) {
+		xine_gui_send_vo_data (xine->stream, XINE_GUI_SEND_COMPLETION_EVENT, ev);
+		return GDK_FILTER_REMOVE;
 	}
+	
+	return GDK_FILTER_CONTINUE;
+}
 
-	vis->display = gdk_x11_drawable_get_xdisplay (draw->window);
+static void gtk_xine_video_info_init (GtkXine *xine, GdkDrawable *window)
+{
+	x11_visual_t *vis = g_malloc (sizeof (x11_visual_t));
+
+	xine->info.video_exit = gtk_xine_x11_video_exit;
+	xine->info.event_filter = gtk_xine_x11_event_filter;
+	xine->info.visual_type = XINE_VISUAL_TYPE_X11;
+	xine->info.visual_data = (void *) vis;
+
+	xine->window = window;
+
+	vis->display = GDK_WINDOW_XDISPLAY (window);
 	vis->screen = gdk_x11_get_default_screen ();
-	vis->d = gdk_x11_drawable_get_xid (draw->window);
+	vis->d = GDK_WINDOW_XID (window);
 	vis->user_data = (void *) xine;
 	vis->dest_size_cb = dest_size_cb;
 	vis->frame_output_cb = frame_output_cb;
-	
-	return 1;
+
+	if (XShmQueryExtension (vis->display))
+		XineCompletionEvent = XShmGetEventBase (vis->display) + ShmCompletion;
 }
 
-static gboolean expose_event_cb (GtkWidget *widget, GdkEventExpose *event, gpointer user_data)
+#elif GTK_XINE_FB
+
+static void gtk_xine_video_info_init (GtkXine *xine, GdkDrawable *window)
 {
-	GtkXine *xine = GTK_XINE (user_data);
+	g_error ("%s(): unimplemented\n", __FUNCTION__);
+}
 
-	xine->x = event->area.x;
-	xine->y = event->area.y;
-	xine->w = event->area.width;
-	xine->h = event->area.height;
-	g_print ("%s(): x=%d, y=%d, w=%d, h=%d\n", __FUNCTION__, xine->x, xine->y, xine->w, xine->h);
+#elif GTK_XINE_WIN32
+
+static void gtk_xine_video_info_init (GtkXine *xine, GdkDrawable *window)
+{
+	g_error ("%s(): unimplemented\n", __FUNCTION__);
+}
+
+#else
+
+/*
+** No video driver at all.
+*/
+
+static void gtk_xine_video_info_init (GtkXine *xine, GdkDrawable *window)
+{
+	xine->info.video_exit = NULL;
+	xine->info.event_filter = NULL;
+	xine->info.visual_type = XINE_VISUAL_TYPE_NONE;
+	xine->info.visual_data = NULL;
+}
+
+#endif
+
+static int configure_event_cb (GtkWidget *drawingarea, GdkEventConfigure *ev, GtkXine *xine)
+{
+	xine->x = ev->x;
+	xine->y = ev->y;
+	xine->w = ev->width;
+	xine->h = ev->height;
+
+	/* this is a hack; somehow, the xlib Display is being passed to xine containing
+	 * the old size.  I'm not sure why it's incorrect, but give gdk/x a second to
+	 * update. */
+	sleep (1);
+	g_print ("\t%s(): x=%d, y=%d, w=%d, h=%d\n", __FUNCTION__, xine->x, xine->y, xine->w, xine->h);
 	return FALSE;
 }
 
-static gboolean configure_event_cb (GtkWidget *widget, GdkEventConfigure *event, gpointer user_data)
+static int expose_event_cb (GtkWidget *drawingarea, GdkEventExpose *ev, GtkXine *xine)
 {
-	GtkXine *xine = GTK_XINE (user_data);
+	XExposeEvent xev;
+	g_print ("Expose Event received (Gdk) (%d %d %d %d)\n", xine->x, xine->y, xine->w, xine->h);
+	if (ev->area.x != xine->x || ev->area.y != xine->y || ev->area.width != xine->w || ev->area.height != xine->h)
+		g_warning ("Window size in event doesn't match current window size!");
+	xev.count = ev->count;
+	xine_gui_send_vo_data (xine->stream, XINE_GUI_SEND_EXPOSE_EVENT, &xev);
 
-	xine->x = event->x;
-	xine->y = event->y;
-	xine->w = event->width;
-	xine->h = event->height;
-	g_print ("%s(): x=%d, y=%d, w=%d, h=%d\n", __FUNCTION__, xine->x, xine->y, xine->w, xine->h);
 	return FALSE;
 }
 
-const char *gtk_xine_set_x11_video_driver (GtkXine *xine, const char *name, GtkWidget *videoarea)
+const char *gtk_xine_set_video_driver (GtkXine *xine, const char *name, GtkWidget *videoarea)
 {
 	const char *const *driver_ids;
-	x11_visual_t vis;
+	GdkColormap *cmap;
+	GdkColor black;
 	int i;
 
 	if (xine->vo_driver) {
 		xine_close_video_driver (xine->xine, xine->vo_driver);
 		xine->vo_driver = NULL;
 	}
-	
+
 	if (strcmp (name, "null") == 0)
 		return name;
 
-	if (!get_visual_info (xine, videoarea, &vis))
-		return "null";
-	g_signal_connect (G_OBJECT (videoarea), "expose_event", G_CALLBACK (expose_event_cb), (void *) xine);
+	if (!GTK_IS_DRAWING_AREA (videoarea)) {
+		g_error (_("xine video driver expects to be supplied with a GtkDrawingArea widget."));
+		return 0;
+	}
+	if (!gtk_widget_get_parent (videoarea)) {
+		g_error (_("xine video driver expects the GtkDrawingArea it gets to have a valid parent window."));
+		return 0;
+	}
+	if (!GTK_WIDGET_VISIBLE (videoarea)) {
+		gtk_widget_realize (videoarea);
+		gtk_widget_show (videoarea);
+	}
+	/* set the background of the drawing area to black.  this needs to be cleaned up. */
+	cmap = gdk_drawable_get_colormap (videoarea->window);
+	gdk_color_black (cmap, &black);
+	gdk_window_set_background (videoarea->window, &black);
+
+	gtk_xine_video_info_init (xine, videoarea->window);
+	if (xine->info.event_filter)
+		gdk_window_add_filter (videoarea->window, xine->info.event_filter, (void *) xine);
 	g_signal_connect (G_OBJECT (videoarea), "configure_event", G_CALLBACK (configure_event_cb), (void *) xine);
+	g_signal_connect (G_OBJECT (videoarea), "expose_event", G_CALLBACK (expose_event_cb), (void *) xine);
 
 	if (strcmp (name, "auto") != 0) {
-		xine->vo_driver = xine_open_video_driver (xine->xine, name, XINE_VISUAL_TYPE_X11, &vis);
+		xine->vo_driver = xine_open_video_driver (xine->xine, name, xine->info.visual_type, xine->info.visual_data);
 		if (xine->vo_driver)
 			return name;
 	}
@@ -608,11 +440,12 @@
 	/* autodetect */
 	driver_ids = xine_list_video_output_plugins (xine->xine);
 	for (i = 0; driver_ids[i] != NULL; i++) {
-		xine->vo_driver = xine_open_video_driver (xine->xine, driver_ids[i], XINE_VISUAL_TYPE_X11, &vis);
+		xine->vo_driver = xine_open_video_driver (xine->xine, driver_ids[i], xine->info.visual_type, xine->info.visual_data);
 		if (xine->vo_driver)
 			return driver_ids[i];
 	}
 
+
 	return "null";
 }
 
@@ -634,6 +467,9 @@
 		xine_close (xine->stream);
 	}
 
+	if (!mrl)
+		return 0;
+
 	if ((i = xine_open (xine->stream, mrl)))
 		xine->current_mrl = g_strdup (mrl);
 
@@ -674,6 +510,29 @@
 	return 1;
 }
 
+GtkXineStatus gtk_xine_get_status (GtkXine *xine)
+{
+	return xine_get_status (xine->stream);
+}
+
+void gtk_xine_event_listener (GtkXine *xine, gtk_xine_event_cb event_cb, void *user_data)
+{
+	xine_event_queue_t *eventq;
+
+	eventq = xine_event_new_queue (xine->stream);
+	xine_event_create_listener_thread (eventq, event_cb, user_data);
+	/* XXX: dispose of queue, or keep it around for multiple regs? */
+}
+
+void gtk_xine_event_send (GtkXine *xine, GtkXineEventType type, void *user_data)
+{
+	xine_event_t event;
+
+	event.type = type;
+	event.data = user_data;
+	xine_event_send (xine->stream, &event);
+}
+
 uint32_t gtk_xine_stream_has_audio (GtkXine *xine)
 {
 	if (!xine->stream)
@@ -703,15 +562,16 @@
 	return xine_get_param (xine->stream, XINE_PARAM_SPEED);
 }
 
-#if 0
 int gtk_xine_set_av_offset (GtkXine *xine, int avoffset)
 {
+	xine_set_param (xine->stream, XINE_PARAM_AV_OFFSET, avoffset);
+	return gtk_xine_get_av_offset (xine);
 }
 
 int gtk_xine_get_av_offset (GtkXine *xine)
 {
+	return xine_get_param (xine->stream, XINE_PARAM_AV_OFFSET);
 }
-#endif
 
 int gtk_xine_set_audio_channel (GtkXine *xine, int channel)
 {
@@ -754,7 +614,7 @@
 			volume = 0;
 		if (volume > 100)
 			volume = 100;
-		xine->warning_cb (str);
+		g_warning (str);
 		g_free (str);
 	}
 
@@ -778,6 +638,39 @@
 	return xine_get_param (xine->stream, XINE_PARAM_AUDIO_MUTE);
 }
 
+GtkXineAspectRatio gtk_xine_set_aspect_ratio (GtkXine *xine, GtkXineAspectRatio ratio)
+{
+	xine_set_param (xine->stream, XINE_PARAM_VO_ASPECT_RATIO, ratio);
+	return gtk_xine_get_aspect_ratio (xine);
+}
+
+GtkXineAspectRatio gtk_xine_get_aspect_ratio (GtkXine *xine)
+{
+	return xine_get_param (xine->stream, XINE_PARAM_VO_ASPECT_RATIO);
+}
+
+int gtk_xine_set_deinterlace (GtkXine *xine, int deinterlace)
+{
+	xine_set_param (xine->stream, XINE_PARAM_VO_DEINTERLACE, deinterlace);
+	return gtk_xine_get_deinterlace (xine);
+}
+
+int gtk_xine_get_deinterlace (GtkXine *xine)
+{
+	return xine_get_param (xine->stream, XINE_PARAM_VO_DEINTERLACE);
+}
+
+int gtk_xine_set_tvmode (GtkXine *xine, int tvmode)
+{
+	xine_set_param (xine->stream, XINE_PARAM_VO_TVMODE, tvmode);
+	return gtk_xine_get_tvmode (xine);
+}
+
+int gtk_xine_get_tvmode (GtkXine *xine)
+{
+	return xine_get_param (xine->stream, XINE_PARAM_VO_TVMODE);
+}
+
 #if 0
 int gtk_xine_set_audio_compression (GtkXine *xine, int level)
 {
@@ -812,11 +705,79 @@
 }
 #endif
 
+int gtk_xine_get_current_position (GtkXine *xine)
+{
+	int pos, a, b;
+
+	if (!xine->stream)
+		return 0;
+
+	if (xine_get_pos_length (xine->stream, &pos, &a, &b))
+		return pos;
+	return 0;
+}
+
+time_t gtk_xine_get_current_time (GtkXine *xine)
+{
+	int time, a, b;
+
+	if (!xine->stream)
+		return 0;
+
+	if (xine_get_pos_length (xine->stream, &a, &time, &b))
+		return (time_t) time;
+	return 0;
+}
+
+time_t gtk_xine_get_stream_length (GtkXine *xine)
+{
+	int len, a, b;
+
+	if (!xine->stream)
+		return 0;
+
+	if (xine_get_pos_length (xine->stream, &a, &b, &len))
+		return (time_t) len;
+	return 0;
+}
+
+int gtk_xine_is_seekable (GtkXine *xine)
+{
+	return xine_get_stream_info(xine->stream, XINE_STREAM_INFO_SEEKABLE);
+}
+
+void gtk_xine_send_videowin_visible (GtkXine *xine, int visible)
+{
+	xine_gui_send_vo_data (xine->stream, XINE_GUI_SEND_VIDEOWIN_VISIBLE, (void *) visible);
+}
+	
+int gtk_xine_get_major_version (GtkXine *xine)
+{
+	int vers, a, b;
+	
+	xine_get_version (&vers, &a, &b);
+	return vers;
+}
+
+int gtk_xine_get_minor_version (GtkXine *xine)
+{
+	int vers, a, b;
+
+	xine_get_version (&a, &vers, &b);
+	return vers;
+}
+
+int gtk_xine_get_sub_version (GtkXine *xine)
+{
+	int vers, a, b;
+
+	xine_get_version (&a, &b, &vers);
+	return vers;
+}
+
 #ifdef GTK_XINE_TEST
 
-#define RCFILE "/home/dilinger/.sinek/config"
-#define MEDIAFILE "/usr/share/xine/skins/xine-ui_logo.mpv"
-//#define MEDIAFILE "/home/dilinger/light_years_DEMO.mp3"
+#define RCFILE "/home/dilinger/.xine/config"
 
 static void create_video_window (const char *title, GtkWidget **frame, GtkWidget **video)
 {
@@ -831,30 +792,32 @@
 	GtkWidget *videowin, *videodisplay, *x;
 
 	gtk_init (&argc, &argv);
-	
+
+	if (argc != 2)
+		g_error ("Usage: %s <mrl>\n", argv[0]);
+
 	create_video_window (_("Xine Video Output"), &videowin, &videodisplay);
+	g_signal_connect (G_OBJECT (videowin), "destroy", G_CALLBACK (gtk_main_quit), NULL);
 
 	x = gtk_xine_new ();
+
 	gtk_xine_config_load (GTK_XINE (x), RCFILE);
 	g_print ("Loaded audio driver '%s'\n", gtk_xine_set_audio_driver (GTK_XINE (x), "auto"));
-	g_print ("Loaded video driver '%s'\n", gtk_xine_set_x11_video_driver (GTK_XINE (x), "auto", videodisplay));
+	g_print ("Loaded video driver '%s'\n", gtk_xine_set_video_driver (GTK_XINE (x), "auto", videodisplay));
 
-	if (gtk_xine_load (GTK_XINE (x), MEDIAFILE))
+	if (gtk_xine_load (GTK_XINE (x), argv[1])) {
 		gtk_xine_play (GTK_XINE (x));
+	}
 
 	if (gtk_xine_stream_has_video (GTK_XINE (x))) {
-		g_print ("'%s' has video, displaying video window\n", MEDIAFILE);
+		g_print ("'%s' has video, displaying video window\n", argv[1]);
 		gtk_widget_show (videowin);
 	}
 
+	gdk_threads_enter ();
 	gtk_main();
-
-//	while (GTK_WIDGET_VISIBLE (videowin))
-//		gtk_main_iteration_do (TRUE);
-
+	gdk_threads_leave ();
 	gtk_widget_destroy (x);
-	gtk_widget_destroy (videodisplay);
-	gtk_widget_destroy (videowin);
 
 	return 0;
 }




-------------------------------------------------------
This SF.NET email is sponsored by: FREE  SSL Guide from Thawte
are you planning your Web Server Security? Click here to get a FREE
Thawte SSL guide and find the answers to all your  SSL security issues.
http://ads.sourceforge.net/cgi-bin/redirect.pl?thaw0026en