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

📄 dw_embed_gtk.c

📁 浏览器的源代码,可移植到嵌入式设备.
💻 C
字号:
#include <gtk/gtk.h>#include "dw_embed_gtk.h"#include "dw_gtk_viewport.h"#include "debug.h"static void Dw_embed_gtk_init           (DwEmbedGtk *embed_gtk);static void Dw_embed_gtk_class_init     (DwEmbedGtkClass *klass);static void Dw_embed_gtk_destroy        (GtkObject *object);static void Dw_embed_gtk_size_request   (DwWidget *widget,                                         DwRequisition *requisition);static gint Dw_embed_gtk_move_idle      (void *data);static void Dw_embed_gtk_size_allocate  (DwWidget *widget,                                         DwAllocation *allocation);static void Dw_embed_gtk_draw           (DwWidget *widget,                                         DwRectangle *area,                                         GdkEventExpose *event);static void Dw_embed_gtk_remove_gtk     (DwEmbedGtk *embed_gtk);static GtkWidgetClass *parent_class;/* * Standard Gtk+ function */GtkType a_Dw_embed_gtk_get_type (void){   static GtkType type = 0;   if (!type) {      GtkTypeInfo info = {         "DwEmbedGtk",         sizeof (DwEmbedGtk),         sizeof (DwEmbedGtkClass),         (GtkClassInitFunc) Dw_embed_gtk_class_init,         (GtkObjectInitFunc) Dw_embed_gtk_init,         (GtkArgSetFunc) NULL,         (GtkArgGetFunc) NULL,         (GtkClassInitFunc) NULL      };      type = gtk_type_unique (DW_TYPE_WIDGET, &info);   }   return type;}/* * Standard Gtk+ function */DwWidget* a_Dw_embed_gtk_new (void){   GtkObject *object;   object = gtk_object_new (DW_TYPE_EMBED_GTK, NULL);   DBG_OBJ_CREATE (object, "DwEmbedGtk");   return DW_WIDGET (object);}/* * Standard Gtk+ function */static void Dw_embed_gtk_init (DwEmbedGtk *embed_gtk){   embed_gtk->child = NULL;   embed_gtk->idle_id = 0;   /*embed_gtk->child_size_request_lock = FALSE;*/}/* * Standard Gtk+ function */static void Dw_embed_gtk_class_init (DwEmbedGtkClass *klass){   GtkObjectClass *object_class;   DwWidgetClass *widget_class;   parent_class = gtk_type_class (DW_TYPE_WIDGET);   object_class = GTK_OBJECT_CLASS (klass);   object_class->destroy = Dw_embed_gtk_destroy;   widget_class = (DwWidgetClass*) klass;   widget_class->size_allocate = Dw_embed_gtk_size_allocate;   widget_class->size_request = Dw_embed_gtk_size_request;   widget_class->draw = Dw_embed_gtk_draw;}/* * Standard Gtk+ function */static void Dw_embed_gtk_destroy (GtkObject *object){   DwEmbedGtk *embed_gtk;   embed_gtk = DW_EMBED_GTK (object);   if (embed_gtk->child)      gtk_object_destroy (GTK_OBJECT (embed_gtk->child));   if (embed_gtk->idle_id != 0)      gtk_idle_remove (embed_gtk->idle_id);   GTK_OBJECT_CLASS(parent_class)->destroy (object);}/* * Standard Gtk+ function */static void Dw_embed_gtk_size_request   (DwWidget *widget,                                         DwRequisition *requisition){   DwEmbedGtk *embed_gtk;   GtkRequisition child_requisition;   embed_gtk = DW_EMBED_GTK (widget);   if (embed_gtk->child) {      /*embed_gtk->child_size_request_lock = TRUE;*/      gtk_widget_size_request (embed_gtk->child, &child_requisition);      /*embed_gtk->child_size_request_lock = FALSE;*/      requisition->width = child_requisition.width;      requisition->ascent = child_requisition.height;      requisition->descent = 0;   } else {      requisition->width = 0;      requisition->ascent = 0;      requisition->descent = 0;   }}/* * Standard Gtk+ function */static gint Dw_embed_gtk_move_idle (void *data){   DwWidget *widget;   DwEmbedGtk *embed_gtk;   widget = DW_WIDGET (data);   embed_gtk = DW_EMBED_GTK (data);   if (embed_gtk->child) {      if (embed_gtk->child->parent)         gtk_layout_move (GTK_LAYOUT (widget->viewport), embed_gtk->child,                          widget->allocation.x, widget->allocation.y);      else         gtk_layout_put (GTK_LAYOUT (widget->viewport), embed_gtk->child,                         widget->allocation.x, widget->allocation.y);   }   embed_gtk->idle_id = 0;   return FALSE;}/* * Standard Gtk+ function */static void Dw_embed_gtk_size_allocate (DwWidget *widget,                                        DwAllocation *allocation){   DwEmbedGtk *embed_gtk;   embed_gtk = DW_EMBED_GTK (widget);   if (embed_gtk->child && widget->viewport) {      if (allocation->width == 0 ||          allocation->ascent + allocation->descent == 0)         gtk_widget_hide (embed_gtk->child);      else {         gtk_widget_show (embed_gtk->child);         if (allocation->width != widget->allocation.width ||             allocation->ascent + allocation->descent             != DW_WIDGET_HEIGHT(widget))            /* todo: try implementing it by gtk_widget_size_allocate */            gtk_widget_set_usize (embed_gtk->child,                                  allocation->width,                                  allocation->ascent + allocation->descent);         if (allocation->x != widget->allocation.x ||             allocation->y != widget->allocation.y) {            /* A simple call to gtk_layout_move does not seem to work, so this               strange idle function. */            if (embed_gtk->idle_id == 0)               embed_gtk->idle_id =                  gtk_idle_add (Dw_embed_gtk_move_idle, (void*) embed_gtk);         }      }   }}static void Dw_embed_gtk_draw (DwWidget *widget,                               DwRectangle *area,                               GdkEventExpose *event){   /* This is the job of GtkDwViewport (resp. the base class GtkLayout). */}/* * This function is called when the embedded Gtk+ widget is destroyed. * Don't use this function directly! */static void Dw_embed_gtk_remove_gtk (DwEmbedGtk *embed_gtk){   embed_gtk->child = NULL;   p_Dw_widget_queue_resize (DW_WIDGET (embed_gtk), 0, TRUE);}/* * This function is called when the embedded Gtk+ widget is focused and * will set the adjustments of the viewport. * Don't use this function directly! */static int Dw_embed_gtk_child_focus_in (DwEmbedGtk *embed_gtk){   DwWidget *widget;   GtkLayout *layout;   gint vx, vy, vw, vh, wx, wy, ww, wh;   widget = DW_WIDGET (embed_gtk);   layout = GTK_LAYOUT (widget->viewport);   vx = layout->xoffset;   vy = layout->yoffset;   vw = GTK_WIDGET(layout)->allocation.width;   vh = GTK_WIDGET(layout)->allocation.height;   wx = widget->allocation.x;   wy = widget->allocation.y;   ww = widget->allocation.width;   wh = DW_WIDGET_HEIGHT(widget);   if (vx > wx)      gtk_adjustment_set_value (layout->hadjustment, wx);   else if (vx < wx + ww - vw)      gtk_adjustment_set_value (layout->hadjustment, wx + ww - vw);   if (vy > wy)      gtk_adjustment_set_value (layout->vadjustment, wy);   else if (vy < wy + wh - vh)      gtk_adjustment_set_value (layout->vadjustment, wy + wh - vh);   return FALSE;}#if 0/* * Called when the embedded Gtk widget emits a "size_request" signal, and used * to resise the embedding Dw widget. * * Currently not used. */static void Dw_embed_gtk_child_size_request (DwEmbedGtk *embed_gtk){   DwWidget *widget;   GtkRequisition child_requisition;   g_return_if_fail (embed_gtk->child);   if (!embed_gtk->child_size_request_lock) {      widget = DW_WIDGET (embed_gtk);      embed_gtk->child_size_request_lock = TRUE;      gtk_widget_size_request (embed_gtk->child, &child_requisition);      embed_gtk->child_size_request_lock = FALSE;      /* Check wether the size has changed at all. */      if (widget->requisition.width != child_requisition.width ||          widget->requisition.ascent != child_requisition.height)         p_Dw_widget_queue_resize (widget, 0, TRUE);   }}#endif/* * Add the Gtk+ widget to be embedded. * If there is already one, you have to destroy it before. */void a_Dw_embed_gtk_add_gtk (DwEmbedGtk *embed_gtk,                             GtkWidget *widget){   /* todo: problems with reparent's? */   g_return_if_fail (embed_gtk->child == NULL);   embed_gtk->child = widget;   if (DW_WIDGET(embed_gtk)->viewport)      gtk_layout_put (GTK_LAYOUT (DW_WIDGET (embed_gtk)->viewport),                      widget,                      DW_WIDGET (embed_gtk)->allocation.x,                      DW_WIDGET (embed_gtk)->allocation.y);   /* todo: We somehow must regognize size changes of the embedded Gtk+    * widget. Can this be done with size_request? Anyway, currently    * deactivated, since it is not used in dillo. */#if 0   gtk_signal_connect_object (GTK_OBJECT (embed_gtk->child),                              "size_request",                              GTK_SIGNAL_FUNC(Dw_embed_gtk_child_size_request),                              GTK_OBJECT (embed_gtk));#endif   /* for setting the adjustments */   gtk_signal_connect_object (GTK_OBJECT (embed_gtk->child),                              "focus_in_event",                              GTK_SIGNAL_FUNC (Dw_embed_gtk_child_focus_in),                              GTK_OBJECT (embed_gtk));   /* todo: An idea: use "remove" signal of DwGtkContainer instead. */   gtk_signal_connect_object (GTK_OBJECT (embed_gtk->child),                              "destroy",                              GTK_SIGNAL_FUNC (Dw_embed_gtk_remove_gtk),                              GTK_OBJECT (embed_gtk));   p_Dw_widget_queue_resize (DW_WIDGET (embed_gtk), 0, TRUE);}

⌨️ 快捷键说明

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