⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gtk_factory.cpp

📁 彩信浏览器
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// This file is part of Ambulant Player, www.ambulantplayer.org.//// Copyright (C) 2003-2007 Stichting CWI, // Kruislaan 413, 1098 SJ Amsterdam, The Netherlands.//// Ambulant Player is free software; you can redistribute it and/or modify// it under the terms of the GNU Lesser General Public License as published by// the Free Software Foundation; either version 2.1 of the License, or// (at your option) any later version.//// Ambulant Player is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the// GNU Lesser General Public License for more details.//// You should have received a copy of the GNU Lesser General Public License// along with Ambulant Player; if not, write to the Free Software// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA //#define AM_DBG if(1)#ifndef AM_DBG#define AM_DBG if(0)#endif #include "ambulant/gui/gtk/gtk_factory.h"#include "ambulant/gui/gtk/gtk_includes.h"#include "ambulant/gui/gtk/gtk_image_renderer.h"#ifdef	WITH_QT_HTML_WIDGET#include "ambulant/gui/gtk/gtk_html_renderer.h"#endif/*WITH_QT_HTML_WIDGET*/#include "ambulant/gui/gtk/gtk_text_renderer.h"#include "ambulant/gui/gtk/gtk_video_renderer.h"using namespace ambulant;using namespace gui::gtk;using namespace net;common::playable_factory *ambulant::gui::gtk::create_gtk_renderer_factory(common::factories *factory){    return new gtk_renderer_factory(factory);}common::window_factory *ambulant::gui::gtk::create_gtk_window_factory(gtk_ambulant_widget* gtk_widget, GMainLoop* loop, common::gui_player* gpl){    return new gtk_window_factory(gtk_widget, loop, gpl);}common::playable_factory *ambulant::gui::gtk::create_gtk_video_factory(common::factories *factory){    return new gtk_video_factory(factory);}// under construction// structure to keep track of the dirty areastruct dirty_area_widget {	lib::rect area;	GtkWidget* widget;	};// Callbacks used to keep synchronization of the different threadsextern "C" {bool gtk_C_callback_helper_queue_draw_area(void *arg){	assert(arg);	dirty_area_widget *r = (dirty_area_widget *)arg;	assert(r != 0);//	ambulant::lib::logger::get_logger()->debug("gtk_C_callback_helper_queue_draw_area with left: %d, top: %d, width: %d, height: %d", r->area.left(), r->area.top(), r->area.width(), r->area.height());	gtk_widget_queue_draw_area(r->widget, r->area.left(), r->area.top(), r->area.width(), r->area.height());//	gtk_widget_queue_draw(r->widget);	delete r;	return false;//	r->release();}}extern "C" {void gtk_C_callback_do_paint_event(void *userdata, GdkEventExpose *event, GtkWidget *widget){	((gtk_ambulant_widget*) userdata)->do_paint_event(event);}}extern "C" {void gtk_C_callback_do_motion_notify_event(void *userdata, GdkEventMotion *event, GtkWidget *widget){	((gtk_ambulant_widget*) userdata)->do_motion_notify_event(event);}}extern "C" {void gtk_C_callback_do_button_release_event(void *userdata, GdkEventButton *event, GtkWidget *widget){	gint s_x, s_y, d_x, d_y;	gtk_ambulant_widget* gaw = (gtk_ambulant_widget*) userdata;	GdkWindow* s_gdkw; /* source window */	GtkWidget* d_gtkw; /* destination widget */	GtkWidget* t_gtkw; /* toplevel widget */		/* Find in the widget stack the widget in which window	   the event source coordinates (s_x,s_y) are defined	*/	if (gaw == NULL || event == NULL)		return; /* cannot handle */ 	s_x = (gint) round (event->x);	s_y = (gint) round (event->y);	s_gdkw = event->window;	d_gtkw = gaw->get_gtk_widget ();	t_gtkw = gtk_widget_get_toplevel (d_gtkw);		for (GtkWidget* a_gtkw = d_gtkw; a_gtkw != NULL; 	     a_gtkw = gtk_widget_get_parent (a_gtkw)) {		if (s_gdkw == a_gtkw->window) {			/* found corresponding GdkWindow in GtkWidget stack */			/* translate if necessary */	    		if (a_gtkw != d_gtkw 			    && gtk_widget_translate_coordinates (a_gtkw, d_gtkw,								 s_x, s_y,								 &d_x, &d_y)) {				event->x = d_x;				event->y = d_y;			}			gaw->do_button_release_event (event);			break;		}		if (a_gtkw == t_gtkw)			break; /* not found */	}}}#ifdef	DUMPPIXMAP/* test if there is something new to see */static GdkPixmap* oldImageP;static boolisEqualToPrevious(GdkPixmap* gpmP) {	return false;	//QImage img = gpmP->convertToImage();	//if (oldImageP != NULL && img == *oldImageP) {	//	AM_DBG lib::logger::get_logger()->debug("isEqualToPrevious: new image not different from old one");	//	return true;	//} else {	//	if (oldImageP != NULL) delete oldImageP;	//	oldImageP = new QImage(img);	//	return false;	//}}/* gdk_pixmap_dump on file */voidgui::gtk::gdk_pixmap_dump(GdkPixmap* gpm, std::string filename) {	if ( ! gpm) return;	GdkPixbuf* pixbuf = gdk_pixbuf_get_from_drawable(NULL, gpm, 0, 0, 0, 0, 0, -1, -1);//QImage img = gpm->convertToImage();	if (pixbuf && ! isEqualToPrevious(gpm)) {		char buf[5];		static int i;		sprintf(buf,"%04d",i++);		std::string newfile = buf + std::string(filename) +".png";		GError* error = NULL;		gdk_pixbuf_save(pixbuf, newfile.c_str(), "png", &error, NULL);		g_object_unref(G_OBJECT(pixbuf));		AM_DBG lib::logger::get_logger()->debug("gdk_pixmap_dump(%s)", newfile.c_str());	}}#endif/*DUMPPIXMAP*/void gui::gtk::gdk_pixmap_bitblt(GdkPixmap* dst, int dst_x, int dst_y, GdkPixmap* src, int src_x, int src_y, int width, int height) {	GdkGC *gc = gdk_gc_new (dst);	gdk_draw_pixmap(GDK_DRAWABLE(dst), gc, GDK_DRAWABLE(src), src_x, src_y,			dst_x, dst_y, width, height);	g_object_unref (G_OBJECT (gc));};//// gtk_renderer_factory//gtk_renderer_factory::gtk_renderer_factory(common::factories *factory):	m_factory(factory){	AM_DBG lib::logger::get_logger()->debug("gtk_renderer factory (0x%x)", (void*) this);}// XXXXcommon::playable *gtk_renderer_factory::new_playable(	common::playable_notification *context,	common::playable_notification::cookie_type cookie,	const lib::node *node,	lib::event_processor *const evp) {	lib::xml_string tag = node->get_qname().second;	common::playable* rv;	if (tag == "img") { 		rv = new gtk_image_renderer(context, cookie, node,						  evp, m_factory);		AM_DBG lib::logger::get_logger()->debug("gtk_renderer_factory: node 0x%x: returning gtk_image_renderer 0x%x", 			(void*) node, (void*) rv);	} else if (tag == "brush") { 		rv = new gtk_fill_renderer(context, cookie, node,					  evp, m_factory);		AM_DBG lib::logger::get_logger()->debug("gtk_renderer_factory: node 0x%x: returning gtk_fill_renderer 0x%x", 			(void*) node, (void*) rv);	} else if ( tag == "text") {#ifdef	WITH_GTK_HTML_WIDGET		net::url url = net::url(node->get_url("src"));		if (url.guesstype() == "text/html") {			rv = new gtk_html_renderer(context, cookie, node, evp, m_factory);			AM_DBG lib::logger::get_logger()->debug("gtk_renderer_factory: node 0x%x: returning gtk_html_renderer 0x%x", (void*) node, (void*) rv);		} else {#endif   /*WITH_GTK_HTML_WIDGET*/		rv = new gtk_text_renderer(context, cookie, node,						 evp, m_factory);		AM_DBG lib::logger::get_logger()->debug("gtk_renderer_factory: node 0x%x: returning gtk_text_renderer 0x%x",			(void*) node, (void*) rv);#ifdef	WITH_GTK_HTML_WIDGET		}#endif/*WITH_QT_HTML_WIDGET*/	} else {		return NULL;	}  return rv;}common::playable *gtk_renderer_factory::new_aux_audio_playable(		common::playable_notification *context,		common::playable_notification::cookie_type cookie,		const lib::node *node,		lib::event_processor *evp,		net::audio_datasource *src){	return NULL;}//// gtk_window_factory//gtk_window_factory::gtk_window_factory( gtk_ambulant_widget* parent_widget, GMainLoop* loop, common::gui_player* gpl):	m_gui_player(gpl),	m_parent_widget(parent_widget){	m_main_loop = loop;	AM_DBG lib::logger::get_logger()->debug("gtk_window_factory (0x%x)", (void*) this);	m_arrow_cursor = gdk_cursor_new(GDK_ARROW);	m_hand1_cursor = gdk_cursor_new(GDK_HAND1);	m_hand2_cursor = gdk_cursor_new(GDK_HAND2);}	gtk_window_factory::~gtk_window_factory( ){	gdk_cursor_unref(m_arrow_cursor);	gdk_cursor_unref(m_hand1_cursor);	gdk_cursor_unref(m_hand2_cursor);}common::gui_window *gtk_window_factory::new_window (const std::string &name,			       lib::size bounds,			       common::gui_events *region){	lib::rect* r = new lib::rect(m_p, bounds);	AM_DBG lib::logger::get_logger()->debug("gtk_window_factory::new_window (0x%x): name=%s %d,%d,%d,%d",		(void*) this, name.c_str(), r->left(),r->top(),r->right(),r->bottom());	ambulant_gtk_window * agtkw = new ambulant_gtk_window(name, r, region);	agtkw->m_main_loop = m_main_loop;	// We don't create this widget anymore MainLoop does it!!	gtk_widget_set_size_request(m_parent_widget->get_gtk_widget(), r->right(), r->bottom());	gtk_widget_set_size_request(gtk_widget_get_toplevel (m_parent_widget->get_gtk_widget()), r->right(), r->bottom()+ 25);	gtk_widget_show(m_parent_widget->get_gtk_widget());//	gtk_ambulant_widget * gtkaw = new gtk_ambulant_widget(name, r, m_parent_widget);		// Wrong!!! I need to add the GUI size//	gtk_widget_set_size_request(GTK_WIDGET (gtk_widget_get_toplevel (gtkaw->get_gtk_widget())), r->right(), r->bottom()+ 25);//	agtkw->set_ambulant_widget(gtkaw);	agtkw->set_ambulant_widget(m_parent_widget);	m_parent_widget->set_gtk_window(agtkw);//	gtkaw->set_gtk_window(agtkw);	AM_DBG lib::logger::get_logger()->debug("gtk_window_factory::new_window(0x%x): ambulant_widget=0x%x gtk_window=0x%x",		(void*) this, (void*) m_parent_widget, (void*) agtkw);	agtkw->set_gui_player(m_gui_player);	agtkw->set_gdk_cursor(GDK_ARROW, m_arrow_cursor);	agtkw->set_gdk_cursor(GDK_HAND1, m_hand1_cursor);	agtkw->set_gdk_cursor(GDK_HAND2, m_hand2_cursor);	return agtkw;}common::bgrenderer *gtk_window_factory::new_background_renderer(const common::region_info 					   *src){	AM_DBG lib::logger::get_logger()->debug("gtk_window_factory::new_background_renderer(0x%x): src=0x%x",		(void*) this, src);	return new gtk_background_renderer(src);}//// gtk_video_factory//gtk_video_factory::~gtk_video_factory(){}common::playable *gtk_video_factory::new_playable(		common::playable_notification *context,		common::playable_notification::cookie_type cookie,		const lib::node *node,		lib::event_processor *evp){	common::playable *rv;		lib::xml_string tag = node->get_qname().second;    AM_DBG lib::logger::get_logger()->debug("gtk_video_factory: node 0x%x:   inspecting %s\n", (void *)node, tag.c_str());	if ( tag == "video") {		rv = new gtk_video_renderer(context, cookie, node, evp, m_factory);		AM_DBG lib::logger::get_logger()->debug("gtk_video_factory: node 0x%x:  returning gtk_video_renderer 0x%x", (void *)node, (void *)rv);	} else {		AM_DBG lib::logger::get_logger()->debug("gtk_video_factory: no renderer for tag \"%s\"", tag.c_str());		return NULL;	}	return rv;}common::playable *gtk_video_factory::new_aux_audio_playable(		common::playable_notification *context,		common::playable_notification::cookie_type cookie,		const lib::node *node,		lib::event_processor *evp,		net::audio_datasource *src){	return NULL;}//// ambulant_gtk_window//ambulant_gtk_window::ambulant_gtk_window(const std::string &name,	   lib::rect* bounds,	   common::gui_events *region):	common::gui_window(region),	m_ambulant_widget(NULL),	m_gui_player(NULL),	m_oldpixmap(NULL),	m_tmppixmap(NULL),	m_arrow_cursor(NULL),	m_hand1_cursor(NULL),	m_hand2_cursor(NULL),	m_fullscreen_count(0),	m_fullscreen_prev_pixmap(NULL),	m_fullscreen_old_pixmap(NULL),	m_fullscreen_engine(NULL),	m_fullscreen_now(0),	m_surface(NULL){	m_pixmap = NULL;	AM_DBG lib::logger::get_logger()->debug("ambulant_gtk_window::ambulant_gtk_window(0x%x)",(void *)this);}ambulant_gtk_window::~ambulant_gtk_window(){		AM_DBG lib::logger::get_logger()->debug("ambulant_gtk_window::~ambulant_gtk_window(0x%x): m_ambulant_widget=0x%x, m_pixmap=0x%x",this,m_ambulant_widget, m_pixmap);	// Note that we don't destroy the widget, only sver the connection.	// the widget itself is destroyed independently.	if (m_ambulant_widget ) {		m_ambulant_widget->set_gtk_window(NULL);//XXXX next delete Reload crashes with gtk, not with qt//		delete m_ambulant_widget;		m_ambulant_widget = NULL;	} 	if (m_pixmap != NULL) {		g_object_unref(G_OBJECT(m_pixmap));		m_pixmap = NULL;	}/** m_oldpixmap not to be deleted, it points to either m_pixmap or m_tmppixmap	if (m_oldpixmap != NULL) {		g_object_unref(G_OBJECT(m_oldpixmap));		m_oldpixmap = NULL;	}**//** m_tmppixmap not to be deleted, it is not a copy anymore	if (m_tmppixmap != NULL) {		g_object_unref(G_OBJECT(m_tmppixmap));		m_tmppixmap = NULL;	}**/}voidambulant_gtk_window::set_gdk_cursor(GdkCursorType gdk_cursor_type, GdkCursor* gdk_cursor){	switch (gdk_cursor_type) {	case GDK_ARROW:	m_arrow_cursor = gdk_cursor;	case GDK_HAND1:	m_hand1_cursor = gdk_cursor;	case GDK_HAND2:	m_hand2_cursor = gdk_cursor;	default:	return;	}}GdkCursor*ambulant_gtk_window::get_gdk_cursor(GdkCursorType gdk_cursor_type){	switch (gdk_cursor_type) {	case GDK_ARROW:	return m_arrow_cursor;	case GDK_HAND1:	return m_hand1_cursor;	case GDK_HAND2:	return m_hand2_cursor;	default:	return NULL;	}}voidambulant_gtk_window::need_redraw(const lib::rect &r){	AM_DBG lib::logger::get_logger()->debug("ambulant_gtk_window::need_redraw(0x%x): ltrb=(%d,%d,%d,%d)", (void *)this, r.left(), r.top(), r.width(), r.height());	if (m_ambulant_widget == NULL) {		lib::logger::get_logger()->error("ambulant_gtk_window::need_redraw(0x%x): m_ambulant_widget == NULL !!!", (void*) this);		return;	}	// we use the parent window for redraw in case this window has been deleted at the time

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -