📄 splash.c
字号:
/*================================================================== * splash.c - Smurf intro splash image functions * * Smurf Sound Font Editor * Copyright (C) 1999-2001 Josh Green * * Code/ideas for splash functions used from: * AbiWord * Copyright (C) 1998 AbiSource, Inc. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. * * To contact the author of this program: * Email: Josh Green <jgreen@users.sourceforge.net> * Smurf homepage: http://smurf.sourceforge.net *==================================================================*/#include "config.h"#include <stdio.h>#include <gtk/gtk.h>#include "splash.h"#ifdef SPLASH#include <png.h>#include "util.h"#define SPLASH_TIMEOUT 2000 /* Delay of splash in ms */extern unsigned char smurf_splash_png[];extern unsigned long smurf_splash_png_sizeof;static void splash_cb_win_destroy (GtkWidget *win);static gboolean splash_cb_expose (GtkWidget *widg, GdkEventExpose *ev);static gboolean splash_cb_button_press (GtkWidget *widg, GdkEventButton *ev);static gint splash_conv_to_rgb (void);static void splash_png_read (png_structp png_ptr, png_bytep data, png_size_t length);static gint splash_png_pos;static guint8 *splash_rgb_data;static GtkWidget *splash_win = NULL;static gint splash_width, splash_height;static gboolean splash_set_timeout;static gint splash_timeout_h;voidsplash_display (gboolean timeout){ GtkWidget *frame; GtkWidget *da; if (splash_win) /* Only one instance at a time :) */ { splash_kill (); /* Kill current instance of splash */ return; } splash_set_timeout = timeout; if (!splash_conv_to_rgb ()) return; /* splash popup window */ splash_win = gtk_window_new (GTK_WINDOW_POPUP); gtk_widget_set_usize (splash_win, splash_width, splash_height); gtk_window_set_policy (GTK_WINDOW (splash_win), FALSE, FALSE, FALSE); gtk_signal_connect (GTK_OBJECT (splash_win), "destroy", GTK_SIGNAL_FUNC (splash_cb_win_destroy), NULL); /* a frame to add depth */ frame = gtk_frame_new (NULL); gtk_container_add (GTK_CONTAINER (splash_win), frame); gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_OUT); gtk_widget_show (frame); /* create a drawing area */ da = gtk_drawing_area_new (); gtk_widget_set_events (da, GDK_ALL_EVENTS_MASK); gtk_widget_set_usize (da, splash_width, splash_height); gtk_signal_connect (GTK_OBJECT (da), "expose_event", GTK_SIGNAL_FUNC (splash_cb_expose), NULL); gtk_signal_connect (GTK_OBJECT (da), "button_press_event", GTK_SIGNAL_FUNC (splash_cb_button_press), NULL); gtk_container_add (GTK_CONTAINER (frame), da); gtk_widget_show (da); gtk_window_set_position (GTK_WINDOW (splash_win), GTK_WIN_POS_CENTER); gtk_widget_show (splash_win);}gboolean /* so it can be used as timeout GSourceFunc */splash_kill (void){ if (splash_win) { if (splash_set_timeout) gtk_timeout_remove (splash_timeout_h); gtk_widget_destroy (splash_win); } return (FALSE);}static voidsplash_cb_win_destroy (GtkWidget *win){ splash_win = NULL; g_free (splash_rgb_data);}static gbooleansplash_cb_expose (GtkWidget *da, GdkEventExpose *ev){ if (splash_win) { gdk_draw_rgb_image (GTK_WIDGET (da)->window, GTK_WIDGET (da)->style->black_gc, 0, 0, splash_width, splash_height, GDK_RGB_DITHER_NORMAL, splash_rgb_data, splash_width * 3); if (splash_set_timeout) { splash_set_timeout = FALSE; splash_timeout_h = gtk_timeout_add (SPLASH_TIMEOUT, (GSourceFunc)splash_kill, NULL); } } return (FALSE);}static gbooleansplash_cb_button_press (GtkWidget *da, GdkEventButton *ev){ splash_kill (); return (FALSE);}static gintsplash_conv_to_rgb (void){ png_structp png_ptr; png_infop info_ptr; gint rowsize; guint8 **rowptrs = NULL; gint i; splash_rgb_data = NULL; /* set rgb data pointer to NULL */ splash_png_pos = 0; /* reset the global splash PNG position */ png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (png_ptr == NULL) return (FAIL); /* Allocate/initialize the memory for image information. REQUIRED. */ info_ptr = png_create_info_struct (png_ptr); if (info_ptr == NULL) { if (splash_rgb_data) g_free (splash_rgb_data); if (rowptrs) g_free (rowptrs); png_destroy_read_struct (&png_ptr, (png_infopp)NULL, (png_infopp)NULL); return (FAIL); } /* Set error handling if you are using the setjmp/longjmp method * (this is the normal method of doing things with libpng). * REQUIRED unless you set up your own error handlers in the * png_create_read_struct() earlier. */ if (setjmp (png_ptr->jmpbuf)) { /* Free all of the memory associated with the png_ptr and info_ptr */ png_destroy_read_struct (&png_ptr, &info_ptr, (png_infopp)NULL); /* If we get here, we had a problem reading the file */ return (FAIL); } png_set_read_fn (png_ptr, NULL, splash_png_read); /* The call to png_read_info() gives us all of the information from * the PNG file before the first IDAT (image data chunk). REQUIRED */ png_read_info (png_ptr, info_ptr); splash_width = png_get_image_width (png_ptr, info_ptr); splash_height = png_get_image_height (png_ptr, info_ptr); /* Expand paletted colors into true RGB triplets */ png_set_expand (png_ptr); /* If we've got images with 16 bits per channel, we don't need that much precision. We'll do fine with 8 bits per channel */ png_set_strip_16 (png_ptr); /* For simplicity, we'll ignore alpha */ png_set_strip_alpha (png_ptr); rowsize = splash_width * 3; /* allocate for 3 bytes each pixel (one for R, G, and B) */ splash_rgb_data = safe_malloc (splash_width * splash_height * 3); if (!splash_rgb_data) { png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL); return (FAIL); } /* allocate for array of row pointers */ rowptrs = safe_malloc (splash_height * sizeof (guint8 *)); if (!rowptrs) { g_free (splash_rgb_data); png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL); return (FAIL); } /* fill array with pointers to start of each row */ for (i = 0; i < splash_height; i++) rowptrs[i] = (guint8 *)splash_rgb_data + i * rowsize; png_read_image (png_ptr, rowptrs); /* Read in the whole image */ g_free(rowptrs); /* read rest of file, and get additional chunks in info_ptr - REQUIRED */ png_read_end (png_ptr, info_ptr); /* clean up after the read, and free any memory allocated - REQUIRED */ png_destroy_read_struct (&png_ptr, &info_ptr, (png_infopp)NULL); return (OK);}static voidsplash_png_read (png_structp png_ptr, png_bytep data, png_size_t length){ memcpy(data, smurf_splash_png + splash_png_pos, length); splash_png_pos += length;}#else /* ifdef SPLASH *//* No Smurfy intro image :( */voidsplash_display (gboolean timeout){}gbooleansplash_kill (void){ return (FALSE);}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -