screenshot.c

Go to the documentation of this file.
00001 /*****************************************************************************
00002  *
00003  * cdebconf - An implementation of the Debian Configuration Management
00004  *            System
00005  *
00006  * $Id$
00007  *
00008  * cdebconf is (c) 2000-2007 Randolph Chung and others under the following
00009  * license.
00010  *
00011  * Redistribution and use in source and binary forms, with or without
00012  * modification, are permitted provided that the following conditions
00013  * are met:
00014  *
00015  * 1. Redistributions of source code must retain the above copyright
00016  * notice, this list of conditions and the following disclaimer.
00017  *
00018  * 2. Redistributions in binary form must reproduce the above copyright
00019  * notice, this list of conditions and the following disclaimer in the
00020  * documentation and/or other materials provided with the distribution.
00021  *
00022  * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
00023  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00024  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00025  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
00026  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00027  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00028  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00029  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00030  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00031  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00032  * SUCH DAMAGE.
00033  *
00034  *****************************************************************************/
00035 
00043 #include "screenshot.h"
00044 
00045 #include <gdk/gdkkeysyms.h>
00046 #include <gtk/gtk.h>
00047 
00048 #include "fe_gtk.h"
00049 #include "fe_data.h"
00050 #include "frontend.h"
00051 #include "ui.h"
00052 #include "di.h"
00053 
00055 #define SCREENSHOT_DIRECTORY "/var/log"
00056 
00063 static gboolean save_screenshot(GdkWindow * gdk_window,
00064                                 const gchar * screenshot_path)
00065 {
00066     GdkPixbuf * pixbuf;
00067     gint x;
00068     gint y;
00069     gint width;
00070     gint height;
00071     gint depth;
00072     gboolean success;
00073 
00074     g_assert(NULL != gdk_window);
00075     g_assert(NULL != screenshot_path);
00076 
00077     gdk_window_get_geometry(gdk_window, &x, &y, &width, &height, &depth);
00078     pixbuf = gdk_pixbuf_get_from_drawable(
00079         NULL /* allocate a new pixbuf */, gdk_window,
00080         gdk_colormap_get_system(), 0 /* src_x */, 0 /* src_y */,
00081         0 /* dest_x */, 0 /* dest_y */, width, height);
00082     if (NULL == pixbuf) {
00083         g_warning("gdk_pixbuf_get_from_drawable failed.");
00084         return FALSE;
00085     }
00086     success = gdk_pixbuf_save(pixbuf, screenshot_path, "png",
00087                               NULL /* no GError */,
00088                               NULL /* end of option list */);
00089     /* This will free the pixbuf, see gdk_pixbuf_get_from_drawable doc. */
00090     g_object_unref(pixbuf);
00091     return success;
00092 }
00093 
00105 static gchar * create_screenshot_path(struct question * question)
00106 {
00107     gchar * question_tag;
00108     gchar * path;
00109     guint i;
00110 
00111     question_tag = g_strdup(question->tag);
00112     /* question_tag will be updated in place */
00113     (void) g_strdelimit(question_tag, "/", '_');
00114 
00115     for (i = 0; TRUE; i++) {
00116         path = g_strdup_printf(SCREENSHOT_DIRECTORY "/%s_%u.png",
00117                                question_tag, i);
00118         if (!g_file_test(path, G_FILE_TEST_EXISTS)) {
00119             break;
00120         }
00121         g_free(path);
00122     }
00123     g_free(question_tag);
00124     return path;
00125 }
00126 
00132 static void popup_success(struct frontend * fe, const gchar * screenshot_path)
00133 {
00134     gchar * title;
00135     char * template;
00136     gchar * message;
00137 
00138     /* XXX: the translated button label might not be suitable for a title
00139      *      in all translations... should use a different template. */
00140     title = fe_gtk_get_text(fe, "debconf/gtk-button-screenshot", "Screenshot");
00141     template = fe_gtk_get_text(fe, "debconf/gtk-screenshot-saved",
00142                                "Screenshot saved as %s");
00143     message = g_strdup_printf(template, screenshot_path);
00144 
00145     if (!fe_gtk_run_message_dialog(fe, title, message)) {
00146         g_warning("fe_gtk_run_message_dialog failed.");
00147     }
00148 }
00149 
00158 static void do_screenshot(struct frontend * fe, GtkWidget * widget)
00159 {
00160     gchar * screenshot_path;
00161     gboolean success;
00162 
00163     screenshot_path = create_screenshot_path(fe->questions);
00164     success = save_screenshot(widget->window, screenshot_path);
00165     if (success) {
00166         popup_success(fe, screenshot_path);
00167     } else {
00168         g_warning("save_screenshot failed.");
00169     }
00170     g_free(screenshot_path);
00171 }
00172 
00180 static gboolean handle_shortcut_key(GtkWidget * widget, GdkEventKey * key,
00181                                     struct frontend * fe)
00182 {
00183     if (GDK_F10 == key->keyval) {
00184         do_screenshot(fe, widget);
00185         return TRUE;
00186     }
00187     return FALSE;
00188 }
00189 
00196 void fe_gtk_add_screenshot_shortcut(struct frontend * fe)
00197 {
00198     struct frontend_data * fe_data = fe->data;
00199 
00200     fe_gtk_add_global_key_handler(fe, fe_data->window,
00201                                   G_CALLBACK(handle_shortcut_key));
00202 }
00203 
00204 #if 0 /* XXX: no screenshot button in the current proposal... */
00205 
00214 void fe_gtk_create_screenshot_button(struct frontend * fe,
00215                                      GtkWidget * container)
00216 {
00217     GtkWidget * button;
00218     char * label;
00219 
00220     label = fe_gtk_get_text(fe, "debconf/gtk-button-screenshot",
00221                             "Screenshot");
00222     /* XXX: check NULL! */
00223     button = gtk_button_new_with_label(label);
00224     g_free(label);
00225 
00226     g_signal_connect(G_OBJECT(button), "clicked",
00227                      G_CALLBACK(do_screenshot), fe);
00228     gtk_widget_set_sensitive(button, FALSE);
00229 
00230     gtk_box_pack_start(GTK_BOX(container), button, TRUE /* expand */,
00231                        TRUE /* fill */, DEFAULT_PADDING);
00232     gtk_button_box_set_child_secondary(GTK_BUTTON_BOX(container), button,
00233                                        TRUE);
00234 
00235     g_object_ref(G_OBJECT(button));
00236     fe_data->di_data->screenshot_button = button;
00237 }
00238 
00245 void fe_gtk_destroy_screenshot_button(struct frontend * fe)
00246 {
00247     struct frontend_data * fe_data = fe->data;
00248 
00249     if (NULL != fe_data->screenshot_button) {
00250         g_object_unref(G_OBJECT(fe_data->screenshot_button));
00251         fe_data->screenshot_button = NULL;
00252         /* widget will really be destroyed by its parent */
00253     }
00254 }
00255 
00262 void fe_gtk_refresh_screenshot_button_label(struct frontend * fe)
00263 {
00264     struct frontend_data * fe_data = fe->data;
00265     
00266     fe_gtk_set_button_label(fe, fe_data->screenshot_button,
00267                             "debconf/gtk-button-screenshot", "Screenshot");
00268 }
00269 
00270 #endif
00271 
00272 /* vim: et sw=4 si
00273  */

Generated on Sat Jul 7 23:41:41 2007 for fe_gtk by  doxygen 1.5.1