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

📄 swfdec_widget.c

📁 Swfdec still is development software, but has also followed a rigid no-crashes-allowed policy. I b
💻 C
字号:
/* Swfdec * Copyright (C) 2006 Benjamin Otte <otte@gnome.org> * * This library 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. *  * This library 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 this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor,  * Boston, MA  02110-1301  USA */#ifdef HAVE_CONFIG_H#include "config.h"#endif#include <math.h>#include "swfdec_widget.h"enum {  PROP_0,  PROP_PLAYER};G_DEFINE_TYPE (SwfdecWidget, swfdec_widget, GTK_TYPE_WIDGET)static gbooleanswfdec_widget_motion_notify (GtkWidget *gtkwidget, GdkEventMotion *event){  SwfdecWidget *widget = SWFDEC_WIDGET (gtkwidget);  int x, y;  gdk_window_get_pointer (gtkwidget->window, &x, &y, NULL);  if (widget->interactive)    swfdec_player_handle_mouse (widget->player, 	x / widget->real_scale, y / widget->real_scale, widget->button);    return FALSE;}static gbooleanswfdec_widget_leave_notify (GtkWidget *gtkwidget, GdkEventCrossing *event){  SwfdecWidget *widget = SWFDEC_WIDGET (gtkwidget);  if (widget->interactive) {    widget->button = 0;    swfdec_player_handle_mouse (widget->player, 	event->x / widget->real_scale, event->y / widget->real_scale, 0);  }  return FALSE;}static gbooleanswfdec_widget_button_press (GtkWidget *gtkwidget, GdkEventButton *event){  SwfdecWidget *widget = SWFDEC_WIDGET (gtkwidget);  if (event->button == 1) {    widget->button = 1;    if (widget->interactive)      swfdec_player_handle_mouse (widget->player, 	  event->x / widget->real_scale, event->y / widget->real_scale, 1);  }  return FALSE;}static gbooleanswfdec_widget_button_release (GtkWidget *gtkwidget, GdkEventButton *event){  SwfdecWidget *widget = SWFDEC_WIDGET (gtkwidget);  if (event->button == 1) {    widget->button = 0;    if (widget->interactive)      swfdec_player_handle_mouse (widget->player, 	  event->x / widget->real_scale, event->y / widget->real_scale, 0);  }  return FALSE;}static gbooleanswfdec_widget_expose (GtkWidget *gtkwidget, GdkEventExpose *event){  SwfdecWidget *widget = SWFDEC_WIDGET (gtkwidget);  cairo_t *cr;  cairo_surface_t *surface = NULL;  if (event->window != gtkwidget->window)    return FALSE;  if (!widget->use_image) {    cr = gdk_cairo_create (gtkwidget->window);  } else {    surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,       event->area.width, event->area.height);    cr = cairo_create (surface);    cairo_translate (cr, -event->area.x, -event->area.y);    cairo_surface_destroy (surface);  }  cairo_scale (cr, widget->real_scale, widget->real_scale);  swfdec_player_render (widget->player, cr,      event->area.x / widget->real_scale, event->area.y / widget->real_scale,       event->area.width / widget->real_scale, event->area.height / widget->real_scale);  if (widget->use_image) {    cairo_t *crw = gdk_cairo_create (gtkwidget->window);    cairo_set_source_surface (crw, surface, event->area.x, event->area.y);    cairo_paint (crw);    cairo_destroy (crw);  }  cairo_destroy (cr);  return FALSE;}static voidswfdec_widget_get_property (GObject *object, guint param_id, GValue *value,     GParamSpec * pspec){  SwfdecWidget *widget = SWFDEC_WIDGET (object);    switch (param_id) {    case PROP_PLAYER:      g_value_set_object (value, widget->player);      break;    default:      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);      break;  }}static voidswfdec_widget_set_property (GObject *object, guint param_id, const GValue *value,    GParamSpec *pspec){  SwfdecWidget *widget = SWFDEC_WIDGET (object);    switch (param_id) {    case PROP_PLAYER:      swfdec_widget_set_player (widget, g_value_get_object (value));      break;    default:      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);      break;  }}static voidswfdec_widget_dispose (GObject *object){  SwfdecWidget *widget = SWFDEC_WIDGET (object);  swfdec_widget_set_player (widget, NULL);  G_OBJECT_CLASS (swfdec_widget_parent_class)->dispose (object);}static voidswfdec_widget_size_allocate (GtkWidget *gtkwidget, GtkAllocation *allocation){  double scale;  int w, h;  SwfdecWidget *widget = SWFDEC_WIDGET (gtkwidget);  gtkwidget->allocation = *allocation;  swfdec_player_get_image_size (widget->player, &w, &h);  if (widget->set_scale > 0.0) {    scale = widget->set_scale;  } else if (widget->player == NULL) {    scale = 1.0;  } else {    if (w != 0 && h != 0)      scale = MIN ((double) allocation->width / w, (double) allocation->height / h);    else      scale = 1.0;  }  w = ceil (w * scale);  h = ceil (h * scale);  if (w > allocation->width)    w = allocation->width;  if (h > allocation->height)    h = allocation->height;  if (GTK_WIDGET_REALIZED (gtkwidget)) {    gdk_window_move_resize (gtkwidget->window, 	allocation->x + (allocation->width - w) / 2,	allocation->y + (allocation->height - h) / 2,	w, h);  }  widget->real_scale = scale;}static voidswfdec_widget_size_request (GtkWidget *gtkwidget, GtkRequisition *req){  double scale;  SwfdecWidget * widget = SWFDEC_WIDGET (gtkwidget);  if (widget->player == NULL) {    req->width = req->height = 0;  } else {    swfdec_player_get_image_size (widget->player, 	  &req->width, &req->height);  }   if (widget->set_scale != 0.0)    scale = widget->set_scale;  else    scale = 1.0;  req->width = ceil (req->width * scale);  req->height = ceil (req->height * scale);}static voidswfdec_widget_update_cursor (SwfdecWidget *widget){  GdkWindow *window = GTK_WIDGET (widget)->window;  GdkDisplay *display = gtk_widget_get_display (GTK_WIDGET (widget));  SwfdecMouseCursor swfcursor;  GdkCursor *cursor;  if (window == NULL)    return;  g_object_get (widget->player, "mouse-cursor", &swfcursor, NULL);  switch (swfcursor) {    case SWFDEC_MOUSE_CURSOR_NONE:      {	GdkBitmap *bitmap;	GdkColor color = { 0, 0, 0, 0 };	char data = 0;	bitmap = gdk_bitmap_create_from_data (window, &data, 1, 1);	if (bitmap == NULL)	  return;	cursor = gdk_cursor_new_from_pixmap (bitmap, bitmap, &color, &color, 0, 0);	gdk_window_set_cursor (window, cursor);	gdk_cursor_unref (cursor);	g_object_unref (bitmap);	break;      }    case SWFDEC_MOUSE_CURSOR_TEXT:      cursor = gdk_cursor_new_for_display (display, GDK_XTERM);      gdk_window_set_cursor (window, cursor);      gdk_cursor_unref (cursor);      break;    case SWFDEC_MOUSE_CURSOR_CLICK:      cursor = gdk_cursor_new_for_display (display, GDK_HAND2);      gdk_window_set_cursor (window, cursor);      gdk_cursor_unref (cursor);      break;    case SWFDEC_MOUSE_CURSOR_NORMAL:      cursor = gdk_cursor_new_for_display (display, GDK_LEFT_PTR);      gdk_window_set_cursor (window, cursor);      gdk_cursor_unref (cursor);      break;    default:      g_warning ("invalid cursor %d", (int) swfcursor);      gdk_window_set_cursor (window, NULL);      break;  }}static voidswfdec_widget_realize (GtkWidget *widget){  GdkWindowAttr attributes;  gint attributes_mask;  GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);  attributes.window_type = GDK_WINDOW_CHILD;  attributes.x = widget->allocation.x;  attributes.y = widget->allocation.y;  attributes.width = widget->allocation.width;  attributes.height = widget->allocation.height;  attributes.wclass = GDK_INPUT_OUTPUT;  attributes.event_mask = gtk_widget_get_events (widget);  attributes.event_mask |= GDK_EXPOSURE_MASK | 			   GDK_BUTTON_PRESS_MASK |			   GDK_BUTTON_RELEASE_MASK |			   GDK_LEAVE_NOTIFY_MASK | 			   GDK_POINTER_MOTION_MASK | 			   GDK_POINTER_MOTION_HINT_MASK;  attributes_mask = GDK_WA_X | GDK_WA_Y;  widget->window = gdk_window_new (gtk_widget_get_parent_window (widget),      &attributes, attributes_mask);  gdk_window_set_user_data (widget->window, widget);  widget->style = gtk_style_attach (widget->style, widget->window);  if (SWFDEC_WIDGET (widget)->player) {    swfdec_widget_update_cursor (SWFDEC_WIDGET (widget));  }}static voidswfdec_widget_class_init (SwfdecWidgetClass * g_class){  GObjectClass *object_class = G_OBJECT_CLASS (g_class);  GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (g_class);  object_class->dispose = swfdec_widget_dispose;  object_class->get_property = swfdec_widget_get_property;  object_class->set_property = swfdec_widget_set_property;  g_object_class_install_property (object_class, PROP_PLAYER,      g_param_spec_object ("player", "player", "player that is displayed",	  SWFDEC_TYPE_PLAYER, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));  widget_class->realize = swfdec_widget_realize;  widget_class->size_request = swfdec_widget_size_request;  widget_class->size_allocate = swfdec_widget_size_allocate;  widget_class->expose_event = swfdec_widget_expose;  widget_class->button_press_event = swfdec_widget_button_press;  widget_class->button_release_event = swfdec_widget_button_release;  widget_class->motion_notify_event = swfdec_widget_motion_notify;  widget_class->leave_notify_event = swfdec_widget_leave_notify;}static voidswfdec_widget_init (SwfdecWidget * widget){  widget->real_scale = 1.0;  widget->interactive = TRUE;}static voidswfdec_widget_invalidate_cb (SwfdecPlayer *player, double x, double y,     double width, double height, SwfdecWidget *widget){  GdkRectangle rect;  if (!GTK_WIDGET_REALIZED (widget))    return;  rect.x = floor (x * widget->real_scale);  rect.y = floor (y * widget->real_scale);  rect.width = ceil ((x + width) * widget->real_scale) - rect.x;  rect.height = ceil ((y + height) * widget->real_scale) - rect.y;  gdk_window_invalidate_rect (GTK_WIDGET (widget)->window, &rect, FALSE);}static voidswfdec_widget_notify_cb (SwfdecPlayer *player, GParamSpec *pspec, SwfdecWidget *widget){  if (g_str_equal (pspec->name, "mouse-cursor")) {    swfdec_widget_update_cursor (widget);  } else if (g_str_equal (pspec->name, "initialized")) {    gtk_widget_queue_resize (GTK_WIDGET (widget));  }}voidswfdec_widget_set_player (SwfdecWidget *widget, SwfdecPlayer *player){  g_return_if_fail (SWFDEC_IS_WIDGET (widget));  g_return_if_fail (player == NULL || SWFDEC_IS_PLAYER (player));    if (widget->player) {    g_signal_handlers_disconnect_by_func (widget->player, swfdec_widget_invalidate_cb, widget);    g_signal_handlers_disconnect_by_func (widget->player, swfdec_widget_notify_cb, widget);    g_object_unref (widget->player);  }  widget->player = player;  if (player) {    g_signal_connect (player, "invalidate", G_CALLBACK (swfdec_widget_invalidate_cb), widget);    g_signal_connect (player, "notify", G_CALLBACK (swfdec_widget_notify_cb), widget);    g_object_ref (player);    swfdec_widget_update_cursor (widget);  } else {    if (GTK_WIDGET (widget)->window)      gdk_window_set_cursor (GTK_WIDGET (widget)->window, NULL);   }  gtk_widget_queue_resize (GTK_WIDGET (widget));}GtkWidget *swfdec_widget_new (SwfdecPlayer *player){  SwfdecWidget *widget;    g_return_val_if_fail (player == NULL || SWFDEC_IS_PLAYER (player), NULL);  widget = g_object_new (SWFDEC_TYPE_WIDGET, "player", player, NULL);  return GTK_WIDGET (widget);}voidswfdec_widget_set_scale	(SwfdecWidget *widget, double scale){  g_return_if_fail (SWFDEC_IS_WIDGET (widget));  g_return_if_fail (scale >= 0.0);  widget->set_scale = scale;  gtk_widget_queue_resize (GTK_WIDGET (widget));}doubleswfdec_widget_get_scale (SwfdecWidget *widget){  g_return_val_if_fail (SWFDEC_IS_WIDGET (widget), 1.0);  return widget->set_scale;}voidswfdec_widget_set_use_image (SwfdecWidget *widget, gboolean use_image){  g_return_if_fail (SWFDEC_IS_WIDGET (widget));  widget->use_image = use_image;  gtk_widget_queue_draw (GTK_WIDGET (widget));}gbooleanswfdec_widget_get_use_image (SwfdecWidget *widget){  g_return_val_if_fail (SWFDEC_IS_WIDGET (widget), 1.0);  return widget->use_image;}voidswfdec_widget_set_interactive (SwfdecWidget *widget, gboolean interactive){  g_return_if_fail (SWFDEC_IS_WIDGET (widget));  widget->interactive = interactive;}gbooleanswfdec_widget_get_interactive (SwfdecWidget *widget){  g_return_val_if_fail (SWFDEC_IS_WIDGET (widget), FALSE);  return widget->interactive;}

⌨️ 快捷键说明

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