Bug Summary

File:cafe-screenshot/src/cafe-screenshot.c
Warning:line 928, column 30
Access of the field 'base_uris' at index 3, while it holds only 3 'char *' elements

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name cafe-screenshot.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -pic-is-pie -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/rootdir/cafe-screenshot/src -fcoverage-compilation-dir=/rootdir/cafe-screenshot/src -resource-dir /usr/lib/llvm-21/lib/clang/21 -D HAVE_CONFIG_H -I . -I ../.. -I . -I . -D CAFELOCALEDIR="/usr/share/locale" -I /usr/include/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include -I /usr/include/sysprof-6 -I /usr/include/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/sysprof-6 -D _REENTRANT -I /usr/include/ctk-3.0 -I /usr/include/pango-1.0 -I /usr/include/cairo -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/glycin-2 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/at-spi-2.0 -I /usr/include/atk-1.0 -I /usr/include/dbus-1.0 -I /usr/lib/x86_64-linux-gnu/dbus-1.0/include -I /usr/include/fribidi -I /usr/include/pixman-1 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/gio-unix-2.0 -I /usr/include/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/sysprof-6 -I /usr/include/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include -I /usr/include/sysprof-6 -I /usr/include/ctk-3.0 -I /usr/include/pango-1.0 -I /usr/include/cairo -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/glycin-2 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/at-spi-2.0 -I /usr/include/atk-1.0 -I /usr/include/dbus-1.0 -I /usr/lib/x86_64-linux-gnu/dbus-1.0/include -I /usr/include/fribidi -I /usr/include/pixman-1 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/gio-unix-2.0 -I /usr/include/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/sysprof-6 -internal-isystem /usr/lib/llvm-21/lib/clang/21/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/15/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -ferror-limit 19 -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -analyzer-checker deadcode.DeadStores -analyzer-checker security.ArrayBound -analyzer-checker unix.cstring.NotNullTerminated -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2026-03-14-180434-92750-1 -x c cafe-screenshot.c
1/* cafe-screenshot.c - Take a screenshot of the desktop
2 *
3 * Copyright (C) 2001 Jonathan Blandford <jrb@alum.mit.edu>
4 * Copyright (C) 2006 Emmanuele Bassi <ebassi@gnome.org>
5 * Copyright (C) 2008 Cosimo Cecchi <cosimoc@gnome.org>
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation; either version 2 of the
10 * License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
20 * USA
21 */
22
23/* THERE ARE NO FEATURE REQUESTS ALLOWED */
24/* IF YOU WANT YOUR OWN FEATURE -- WRITE THE DAMN THING YOURSELF (-: */
25/* MAYBE I LIED... -jrb */
26
27#include <config.h>
28#include <cdk/cdkx.h>
29#include <cdk/cdkkeysyms.h>
30#include <sys/types.h>
31#include <sys/stat.h>
32#include <sys/wait.h>
33#include <fcntl.h>
34#include <unistd.h>
35#include <stdlib.h>
36#include <errno(*__errno_location ()).h>
37#include <signal.h>
38#include <glib-unix1.h>
39#include <locale.h>
40#include <glib/gi18n.h>
41#include <gio/gio.h>
42#include <pwd.h>
43#include <X11/Xutil.h>
44#include <kanberra-ctk.h>
45
46#include "screenshot-shadow.h"
47#include "screenshot-utils.h"
48#include "screenshot-save.h"
49#include "screenshot-dialog.h"
50#include "screenshot-xfer.h"
51
52#define SCREENSHOOTER_ICON"applets-screenshooter" "applets-screenshooter"
53
54#define CAFE_SCREENSHOT_SCHEMA"org.cafe.screenshot" "org.cafe.screenshot"
55#define INCLUDE_BORDER_KEY"include-border" "include-border"
56#define INCLUDE_POINTER_KEY"include-pointer" "include-pointer"
57#define LAST_SAVE_DIRECTORY_KEY"last-save-directory" "last-save-directory"
58#define BORDER_EFFECT_KEY"border-effect" "border-effect"
59#define DELAY_KEY"delay" "delay"
60#define BAUL_PREFERENCES_SCHEMA"org.cafe.baul.preferences" "org.cafe.baul.preferences"
61
62enum
63{
64 COLUMN_NICK,
65 COLUMN_LABEL,
66 COLUMN_ID,
67
68 N_COLUMNS
69};
70
71typedef enum {
72 SCREENSHOT_EFFECT_NONE,
73 SCREENSHOT_EFFECT_SHADOW,
74 SCREENSHOT_EFFECT_BORDER
75} ScreenshotEffectType;
76
77typedef enum
78{
79 TEST_LAST_DIR = 0,
80 TEST_DESKTOP = 1,
81 TEST_TMP = 2,
82} TestType;
83
84typedef struct
85{
86 char *base_uris[3];
87 char *retval;
88 int iteration;
89 TestType type;
90 CdkWindow *window;
91 CdkRectangle *rectangle;
92} AsyncExistenceJob;
93
94static GdkPixbuf *screenshot = NULL((void*)0);
95
96/* Global variables*/
97static char *last_save_dir = NULL((void*)0);
98static char *temporary_file = NULL((void*)0);
99static gboolean save_immediately = FALSE(0);
100static GSettings *settings = NULL((void*)0);
101static gboolean interactive_arg = FALSE(0);
102static guint delay_arg = 0;
103
104/* Options */
105static gboolean noninteractive_clipboard_arg = FALSE(0);
106static gboolean take_window_shot = FALSE(0);
107static gboolean take_area_shot = FALSE(0);
108static gboolean include_border = FALSE(0);
109static gboolean include_pointer = TRUE(!(0));
110static char *border_effect = NULL((void*)0);
111static guint delay = 0;
112
113/* some local prototypes */
114static void display_help (CtkWindow *parent);
115static void save_done_notification (gpointer data);
116static char *get_desktop_dir (void);
117static void save_options (void);
118
119static CtkWidget *border_check = NULL((void*)0);
120static CtkWidget *effect_combo = NULL((void*)0);
121static CtkWidget *effect_label = NULL((void*)0);
122static CtkWidget *effects_vbox = NULL((void*)0);
123static CtkWidget *delay_hbox = NULL((void*)0);
124
125void loop_dialog_screenshot ();
126
127static void
128display_help (CtkWindow *parent)
129{
130 GError *error = NULL((void*)0);
131
132 ctk_show_uri_on_window (parent,
133 "help:cafe-user-guide/goseditmainmenu-53",
134 ctk_get_current_event_time (),
135 &error);
136
137 if (error)
138 {
139 screenshot_show_gerror_dialog (parent,
140 _("Error loading the help page")gettext ("Error loading the help page"),
141 error);
142 g_error_free (error);
143 }
144}
145
146static void
147interactive_dialog_response_cb (CtkDialog *dialog,
148 gint response,
149 gpointer user_data)
150{
151 switch (response)
152 {
153 case CTK_RESPONSE_HELP:
154 g_signal_stop_emission_by_name (dialog, "response");
155 display_help (CTK_WINDOW (dialog)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog)), ((ctk_window_get_type ()))))))
);
156 break;
157 default:
158 ctk_widget_hide (CTK_WIDGET (dialog)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog)), ((ctk_widget_get_type ()))))))
);
159 break;
160 }
161}
162
163#define TARGET_TOGGLE_DESKTOP0 0
164#define TARGET_TOGGLE_WINDOW1 1
165#define TARGET_TOGGLE_AREA2 2
166
167static void
168target_toggled_cb (CtkToggleButton *button,
169 gpointer data)
170{
171 int target_toggle = GPOINTER_TO_INT (data)((gint) (glong) (data));
172
173 if (ctk_toggle_button_get_active (button))
174 {
175 take_window_shot = (target_toggle == TARGET_TOGGLE_WINDOW1);
176 take_area_shot = (target_toggle == TARGET_TOGGLE_AREA2);
177
178 ctk_widget_set_sensitive (border_check, take_window_shot);
179 ctk_widget_set_sensitive (effect_combo, take_window_shot);
180 ctk_widget_set_sensitive (effect_label, take_window_shot);
181
182 ctk_widget_set_sensitive (delay_hbox, !take_area_shot);
183 ctk_widget_set_sensitive (effects_vbox, !take_area_shot);
184 }
185}
186
187static void
188delay_spin_value_changed_cb (CtkSpinButton *button)
189{
190 delay = ctk_spin_button_get_value_as_int (button);
191}
192
193static void
194include_border_toggled_cb (CtkToggleButton *button,
195 gpointer data)
196{
197 include_border = ctk_toggle_button_get_active (button);
198}
199
200static void
201include_pointer_toggled_cb (CtkToggleButton *button,
202 gpointer data)
203{
204 include_pointer = ctk_toggle_button_get_active (button);
205}
206
207static void
208effect_combo_changed_cb (CtkComboBox *combo,
209 gpointer user_data)
210{
211 CtkTreeIter iter;
212
213 if (ctk_combo_box_get_active_iter (combo, &iter))
214 {
215 CtkTreeModel *model;
216 gchar *effect;
217
218 model = ctk_combo_box_get_model (combo);
219 ctk_tree_model_get (model, &iter, COLUMN_NICK, &effect, -1);
220
221 g_assert (effect != NULL)do { if (effect != ((void*)0)) ; else g_assertion_message_expr
(((gchar*) 0), "cafe-screenshot.c", 221, ((const char*) (__func__
)), "effect != NULL"); } while (0)
;
222
223 g_free (border_effect);
224 border_effect = effect; /* gets free'd later */
225 }
226}
227
228static gint
229key_press_cb (CtkWidget* widget, CdkEventKey* event, gpointer data)
230{
231 if (event->keyval == CDK_KEY_F10xffbe)
232 {
233 display_help (CTK_WINDOW (widget)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_window_get_type ()))))))
);
234 return TRUE(!(0));
235 }
236
237 return FALSE(0);
238}
239
240typedef struct {
241 ScreenshotEffectType id;
242 const gchar *label;
243 const gchar *nick;
244} ScreenshotEffect;
245
246/* Translators:
247 * these are the names of the effects available which will be
248 * displayed inside a combo box in interactive mode for the user
249 * to chooser.
250 */
251static const ScreenshotEffect effects[] = {
252 { SCREENSHOT_EFFECT_NONE, N_("None")("None"), "none" },
253 { SCREENSHOT_EFFECT_SHADOW, N_("Drop shadow")("Drop shadow"), "shadow" },
254 { SCREENSHOT_EFFECT_BORDER, N_("Border")("Border"), "border" }
255};
256
257static guint n_effects = G_N_ELEMENTS (effects)(sizeof (effects) / sizeof ((effects)[0]));
258
259static CtkWidget *
260create_effects_combo (void)
261{
262 CtkWidget *retval;
263 CtkListStore *model;
264 CtkCellRenderer *renderer;
265 gint i;
266
267 model = ctk_list_store_new (N_COLUMNS,
268 G_TYPE_STRING((GType) ((16) << (2))),
269 G_TYPE_STRING((GType) ((16) << (2))),
270 G_TYPE_UINT((GType) ((7) << (2))));
271
272 for (i = 0; i < n_effects; i++)
273 {
274 CtkTreeIter iter;
275
276 ctk_list_store_insert (model, &iter, i);
277 ctk_list_store_set (model, &iter,
278 COLUMN_ID, effects[i].id,
279 COLUMN_LABEL, gettext (effects[i].label),
280 COLUMN_NICK, effects[i].nick,
281 -1);
282 }
283
284 retval = ctk_combo_box_new ();
285 ctk_combo_box_set_model (CTK_COMBO_BOX (retval)((((CtkComboBox*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((retval)), ((ctk_combo_box_get_type ()))))))
,
286 CTK_TREE_MODEL (model)((((CtkTreeModel*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((model)), ((ctk_tree_model_get_type ()))))))
);
287 g_object_unref (model);
288
289 switch (border_effect[0])
290 {
291 case 's': /* shadow */
292 ctk_combo_box_set_active (CTK_COMBO_BOX (retval)((((CtkComboBox*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((retval)), ((ctk_combo_box_get_type ()))))))
,
293 SCREENSHOT_EFFECT_SHADOW);
294 break;
295 case 'b': /* border */
296 ctk_combo_box_set_active (CTK_COMBO_BOX (retval)((((CtkComboBox*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((retval)), ((ctk_combo_box_get_type ()))))))
,
297 SCREENSHOT_EFFECT_BORDER);
298 break;
299 case 'n': /* none */
300 ctk_combo_box_set_active (CTK_COMBO_BOX (retval)((((CtkComboBox*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((retval)), ((ctk_combo_box_get_type ()))))))
,
301 SCREENSHOT_EFFECT_NONE);
302 break;
303 default:
304 break;
305 }
306
307 renderer = ctk_cell_renderer_text_new ();
308 ctk_cell_layout_pack_start (CTK_CELL_LAYOUT (retval)((((CtkCellLayout*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((retval)), ((ctk_cell_layout_get_type ()))))))
, renderer, TRUE(!(0)));
309 ctk_cell_layout_set_attributes (CTK_CELL_LAYOUT (retval)((((CtkCellLayout*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((retval)), ((ctk_cell_layout_get_type ()))))))
, renderer,
310 "text", COLUMN_LABEL,
311 NULL((void*)0));
312
313 g_signal_connect (retval, "changed",g_signal_connect_data ((retval), ("changed"), (((GCallback) (
effect_combo_changed_cb))), (((void*)0)), ((void*)0), (GConnectFlags
) 0)
314 G_CALLBACK (effect_combo_changed_cb),g_signal_connect_data ((retval), ("changed"), (((GCallback) (
effect_combo_changed_cb))), (((void*)0)), ((void*)0), (GConnectFlags
) 0)
315 NULL)g_signal_connect_data ((retval), ("changed"), (((GCallback) (
effect_combo_changed_cb))), (((void*)0)), ((void*)0), (GConnectFlags
) 0)
;
316
317 return retval;
318}
319
320static void
321create_effects_frame (CtkWidget *outer_vbox,
322 const gchar *frame_title)
323{
324 CtkWidget *main_vbox, *vbox, *hbox;
325 CtkWidget *label;
326 CtkWidget *check;
327 CtkWidget *combo;
328 gchar *title;
329
330 main_vbox = ctk_box_new (CTK_ORIENTATION_VERTICAL, 6);
331 ctk_widget_set_sensitive (main_vbox, !take_area_shot);
332 ctk_box_pack_start (CTK_BOX (outer_vbox)((((CtkBox*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((outer_vbox)), ((ctk_box_get_type ()))))))
, main_vbox, FALSE(0), FALSE(0), 0);
333 ctk_widget_show (main_vbox);
334 effects_vbox = main_vbox;
335
336 title = g_strconcat ("<b>", frame_title, "</b>", NULL((void*)0));
337 label = ctk_label_new (title);
338 ctk_label_set_use_markup (CTK_LABEL (label)((((CtkLabel*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((label)), ((ctk_label_get_type ()))))))
, TRUE(!(0)));
339 ctk_label_set_xalign (CTK_LABEL (label)((((CtkLabel*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((label)), ((ctk_label_get_type ()))))))
, 0.0);
340 ctk_label_set_yalign (CTK_LABEL (label)((((CtkLabel*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((label)), ((ctk_label_get_type ()))))))
, 0.5);
341 ctk_box_pack_start (CTK_BOX (main_vbox)((((CtkBox*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((main_vbox)), ((ctk_box_get_type ()))))))
, label, FALSE(0), FALSE(0), 0);
342 ctk_widget_show (label);
343 g_free (title);
344
345 hbox = ctk_box_new (CTK_ORIENTATION_HORIZONTAL, 12);
346 ctk_box_pack_start (CTK_BOX (main_vbox)((((CtkBox*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((main_vbox)), ((ctk_box_get_type ()))))))
, hbox, FALSE(0), FALSE(0), 0);
347 ctk_widget_show (hbox);
348
349 vbox = ctk_box_new (CTK_ORIENTATION_VERTICAL, 6);
350 ctk_box_pack_start (CTK_BOX (hbox)((((CtkBox*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((hbox)), ((ctk_box_get_type ()))))))
, vbox, FALSE(0), FALSE(0), 0);
351 ctk_widget_set_margin_start (vbox, 12);
352 ctk_widget_show (vbox);
353
354 /** Include pointer **/
355 check = ctk_check_button_new_with_mnemonic (_("Include _pointer")gettext ("Include _pointer"));
356 ctk_toggle_button_set_active (CTK_TOGGLE_BUTTON (check)((((CtkToggleButton*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((check)), ((ctk_toggle_button_get_type ()))))))
, include_pointer);
357 g_signal_connect (check, "toggled",g_signal_connect_data ((check), ("toggled"), (((GCallback) (include_pointer_toggled_cb
))), (((void*)0)), ((void*)0), (GConnectFlags) 0)
358 G_CALLBACK (include_pointer_toggled_cb),g_signal_connect_data ((check), ("toggled"), (((GCallback) (include_pointer_toggled_cb
))), (((void*)0)), ((void*)0), (GConnectFlags) 0)
359 NULL)g_signal_connect_data ((check), ("toggled"), (((GCallback) (include_pointer_toggled_cb
))), (((void*)0)), ((void*)0), (GConnectFlags) 0)
;
360 ctk_box_pack_start (CTK_BOX (vbox)((((CtkBox*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((vbox)), ((ctk_box_get_type ()))))))
, check, FALSE(0), FALSE(0), 0);
361 ctk_widget_show (check);
362
363 /** Include window border **/
364 check = ctk_check_button_new_with_mnemonic (_("Include the window _border")gettext ("Include the window _border"));
365 ctk_widget_set_sensitive (check, take_window_shot);
366 ctk_toggle_button_set_active (CTK_TOGGLE_BUTTON (check)((((CtkToggleButton*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((check)), ((ctk_toggle_button_get_type ()))))))
, include_border);
367 g_signal_connect (check, "toggled",g_signal_connect_data ((check), ("toggled"), (((GCallback) (include_border_toggled_cb
))), (((void*)0)), ((void*)0), (GConnectFlags) 0)
368 G_CALLBACK (include_border_toggled_cb),g_signal_connect_data ((check), ("toggled"), (((GCallback) (include_border_toggled_cb
))), (((void*)0)), ((void*)0), (GConnectFlags) 0)
369 NULL)g_signal_connect_data ((check), ("toggled"), (((GCallback) (include_border_toggled_cb
))), (((void*)0)), ((void*)0), (GConnectFlags) 0)
;
370 ctk_box_pack_start (CTK_BOX (vbox)((((CtkBox*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((vbox)), ((ctk_box_get_type ()))))))
, check, FALSE(0), FALSE(0), 0);
371 ctk_widget_show (check);
372 border_check = check;
373
374 /** Effects **/
375 hbox = ctk_box_new (CTK_ORIENTATION_HORIZONTAL, 12);
376 ctk_box_pack_start (CTK_BOX (vbox)((((CtkBox*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((vbox)), ((ctk_box_get_type ()))))))
, hbox, FALSE(0), FALSE(0), 0);
377 ctk_widget_show (hbox);
378
379 label = ctk_label_new_with_mnemonic (_("Apply _effect:")gettext ("Apply _effect:"));
380 ctk_widget_set_sensitive (label, take_window_shot);
381 ctk_label_set_xalign (CTK_LABEL (label)((((CtkLabel*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((label)), ((ctk_label_get_type ()))))))
, 0.0);
382 ctk_label_set_yalign (CTK_LABEL (label)((((CtkLabel*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((label)), ((ctk_label_get_type ()))))))
, 0.5);
383 ctk_box_pack_start (CTK_BOX (hbox)((((CtkBox*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((hbox)), ((ctk_box_get_type ()))))))
, label, FALSE(0), FALSE(0), 0);
384 ctk_widget_show (label);
385 effect_label = label;
386
387 combo = create_effects_combo ();
388 ctk_widget_set_sensitive (combo, take_window_shot);
389 ctk_box_pack_start (CTK_BOX (hbox)((((CtkBox*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((hbox)), ((ctk_box_get_type ()))))))
, combo, FALSE(0), FALSE(0), 0);
390 ctk_label_set_mnemonic_widget (CTK_LABEL (label)((((CtkLabel*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((label)), ((ctk_label_get_type ()))))))
, combo);
391 ctk_widget_show (combo);
392 effect_combo = combo;
393}
394
395static void
396create_screenshot_frame (CtkWidget *outer_vbox,
397 const gchar *frame_title)
398{
399 CtkWidget *main_vbox, *vbox, *hbox;
400 CtkWidget *radio;
401 CtkWidget *image;
402 CtkWidget *spin;
403 CtkWidget *label;
404 CtkAdjustment *adjust;
405 GSList *group;
406 gchar *title;
407
408 main_vbox = ctk_box_new (CTK_ORIENTATION_VERTICAL, 6);
409 ctk_box_pack_start (CTK_BOX (outer_vbox)((((CtkBox*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((outer_vbox)), ((ctk_box_get_type ()))))))
, main_vbox, FALSE(0), FALSE(0), 0);
410 ctk_widget_show (main_vbox);
411
412 title = g_strconcat ("<b>", frame_title, "</b>", NULL((void*)0));
413 label = ctk_label_new (title);
414 ctk_label_set_use_markup (CTK_LABEL (label)((((CtkLabel*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((label)), ((ctk_label_get_type ()))))))
, TRUE(!(0)));
415 ctk_label_set_xalign (CTK_LABEL (label)((((CtkLabel*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((label)), ((ctk_label_get_type ()))))))
, 0.0);
416 ctk_label_set_yalign (CTK_LABEL (label)((((CtkLabel*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((label)), ((ctk_label_get_type ()))))))
, 0.5);
417 ctk_box_pack_start (CTK_BOX (main_vbox)((((CtkBox*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((main_vbox)), ((ctk_box_get_type ()))))))
, label, FALSE(0), FALSE(0), 0);
418 ctk_widget_show (label);
419 g_free (title);
420
421 hbox = ctk_box_new (CTK_ORIENTATION_HORIZONTAL, 12);
422 ctk_box_pack_start (CTK_BOX (main_vbox)((((CtkBox*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((main_vbox)), ((ctk_box_get_type ()))))))
, hbox, FALSE(0), FALSE(0), 0);
423 ctk_widget_show (hbox);
424
425 image = ctk_image_new_from_icon_name (SCREENSHOOTER_ICON"applets-screenshooter",
426 CTK_ICON_SIZE_DIALOG);
427
428 ctk_box_pack_start (CTK_BOX (hbox)((((CtkBox*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((hbox)), ((ctk_box_get_type ()))))))
, image, FALSE(0), FALSE(0), 0);
429 ctk_widget_set_valign (image, CTK_ALIGN_START);
430 ctk_widget_show (image);
431
432 vbox = ctk_box_new (CTK_ORIENTATION_VERTICAL, 6);
433 ctk_box_pack_start (CTK_BOX (hbox)((((CtkBox*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((hbox)), ((ctk_box_get_type ()))))))
, vbox, FALSE(0), FALSE(0), 0);
434 ctk_widget_show (vbox);
435
436 /** Grab whole desktop **/
437 group = NULL((void*)0);
438 radio = ctk_radio_button_new_with_mnemonic (group,
439 _("Grab the whole _desktop")gettext ("Grab the whole _desktop"));
440 if (take_window_shot || take_area_shot)
441 ctk_toggle_button_set_active (CTK_TOGGLE_BUTTON (radio)((((CtkToggleButton*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((radio)), ((ctk_toggle_button_get_type ()))))))
, FALSE(0));
442 g_signal_connect (radio, "toggled",g_signal_connect_data ((radio), ("toggled"), (((GCallback) (target_toggled_cb
))), (((gpointer) (glong) (0))), ((void*)0), (GConnectFlags) 0
)
443 G_CALLBACK (target_toggled_cb),g_signal_connect_data ((radio), ("toggled"), (((GCallback) (target_toggled_cb
))), (((gpointer) (glong) (0))), ((void*)0), (GConnectFlags) 0
)
444 GINT_TO_POINTER (TARGET_TOGGLE_DESKTOP))g_signal_connect_data ((radio), ("toggled"), (((GCallback) (target_toggled_cb
))), (((gpointer) (glong) (0))), ((void*)0), (GConnectFlags) 0
)
;
445 ctk_box_pack_start (CTK_BOX (vbox)((((CtkBox*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((vbox)), ((ctk_box_get_type ()))))))
, radio, FALSE(0), FALSE(0), 0);
446 group = ctk_radio_button_get_group (CTK_RADIO_BUTTON (radio)((((CtkRadioButton*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((radio)), ((ctk_radio_button_get_type ()))))))
);
447 ctk_widget_show (radio);
448
449 /** Grab current window **/
450 radio = ctk_radio_button_new_with_mnemonic (group,
451 _("Grab the current _window")gettext ("Grab the current _window"));
452 if (take_window_shot)
453 ctk_toggle_button_set_active (CTK_TOGGLE_BUTTON (radio)((((CtkToggleButton*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((radio)), ((ctk_toggle_button_get_type ()))))))
, TRUE(!(0)));
454 g_signal_connect (radio, "toggled",g_signal_connect_data ((radio), ("toggled"), (((GCallback) (target_toggled_cb
))), (((gpointer) (glong) (1))), ((void*)0), (GConnectFlags) 0
)
455 G_CALLBACK (target_toggled_cb),g_signal_connect_data ((radio), ("toggled"), (((GCallback) (target_toggled_cb
))), (((gpointer) (glong) (1))), ((void*)0), (GConnectFlags) 0
)
456 GINT_TO_POINTER (TARGET_TOGGLE_WINDOW))g_signal_connect_data ((radio), ("toggled"), (((GCallback) (target_toggled_cb
))), (((gpointer) (glong) (1))), ((void*)0), (GConnectFlags) 0
)
;
457 ctk_box_pack_start (CTK_BOX (vbox)((((CtkBox*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((vbox)), ((ctk_box_get_type ()))))))
, radio, FALSE(0), FALSE(0), 0);
458 group = ctk_radio_button_get_group (CTK_RADIO_BUTTON (radio)((((CtkRadioButton*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((radio)), ((ctk_radio_button_get_type ()))))))
);
459 ctk_widget_show (radio);
460
461 /** Grab area of the desktop **/
462 radio = ctk_radio_button_new_with_mnemonic (group,
463 _("Select _area to grab")gettext ("Select _area to grab"));
464 if (take_area_shot)
465 ctk_toggle_button_set_active (CTK_TOGGLE_BUTTON (radio)((((CtkToggleButton*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((radio)), ((ctk_toggle_button_get_type ()))))))
, TRUE(!(0)));
466 g_signal_connect (radio, "toggled",g_signal_connect_data ((radio), ("toggled"), (((GCallback) (target_toggled_cb
))), (((gpointer) (glong) (2))), ((void*)0), (GConnectFlags) 0
)
467 G_CALLBACK (target_toggled_cb),g_signal_connect_data ((radio), ("toggled"), (((GCallback) (target_toggled_cb
))), (((gpointer) (glong) (2))), ((void*)0), (GConnectFlags) 0
)
468 GINT_TO_POINTER (TARGET_TOGGLE_AREA))g_signal_connect_data ((radio), ("toggled"), (((GCallback) (target_toggled_cb
))), (((gpointer) (glong) (2))), ((void*)0), (GConnectFlags) 0
)
;
469 ctk_box_pack_start (CTK_BOX (vbox)((((CtkBox*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((vbox)), ((ctk_box_get_type ()))))))
, radio, FALSE(0), FALSE(0), 0);
470 ctk_widget_show (radio);
471
472 /** Grab after delay **/
473 delay_hbox = ctk_box_new (CTK_ORIENTATION_HORIZONTAL, 6);
474 ctk_widget_set_sensitive (delay_hbox, !take_area_shot);
475 ctk_box_pack_start (CTK_BOX (vbox)((((CtkBox*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((vbox)), ((ctk_box_get_type ()))))))
, delay_hbox, FALSE(0), FALSE(0), 0);
476 ctk_widget_show (delay_hbox);
477
478 /* translators: this is the first part of the "grab after a
479 * delay of <spin button> seconds".
480 */
481 label = ctk_label_new_with_mnemonic (_("Grab _after a delay of")gettext ("Grab _after a delay of"));
482 ctk_label_set_xalign (CTK_LABEL (label)((((CtkLabel*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((label)), ((ctk_label_get_type ()))))))
, 0.0);
483 ctk_label_set_yalign (CTK_LABEL (label)((((CtkLabel*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((label)), ((ctk_label_get_type ()))))))
, 0.5);
484 ctk_box_pack_start (CTK_BOX (delay_hbox)((((CtkBox*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((delay_hbox)), ((ctk_box_get_type ()))))))
, label, FALSE(0), FALSE(0), 0);
485 ctk_widget_show (label);
486
487 adjust = CTK_ADJUSTMENT (ctk_adjustment_new ((gdouble) delay,((((CtkAdjustment*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((ctk_adjustment_new ((gdouble) delay, 0.0, 99.0, 1.0, 1.0
, 0.0))), ((ctk_adjustment_get_type ()))))))
488 0.0, 99.0,((((CtkAdjustment*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((ctk_adjustment_new ((gdouble) delay, 0.0, 99.0, 1.0, 1.0
, 0.0))), ((ctk_adjustment_get_type ()))))))
489 1.0, 1.0,((((CtkAdjustment*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((ctk_adjustment_new ((gdouble) delay, 0.0, 99.0, 1.0, 1.0
, 0.0))), ((ctk_adjustment_get_type ()))))))
490 0.0))((((CtkAdjustment*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((ctk_adjustment_new ((gdouble) delay, 0.0, 99.0, 1.0, 1.0
, 0.0))), ((ctk_adjustment_get_type ()))))))
;
491 spin = ctk_spin_button_new (adjust, 1.0, 0);
492 g_signal_connect (spin, "value-changed",g_signal_connect_data ((spin), ("value-changed"), (((GCallback
) (delay_spin_value_changed_cb))), (((void*)0)), ((void*)0), (
GConnectFlags) 0)
493 G_CALLBACK (delay_spin_value_changed_cb),g_signal_connect_data ((spin), ("value-changed"), (((GCallback
) (delay_spin_value_changed_cb))), (((void*)0)), ((void*)0), (
GConnectFlags) 0)
494 NULL)g_signal_connect_data ((spin), ("value-changed"), (((GCallback
) (delay_spin_value_changed_cb))), (((void*)0)), ((void*)0), (
GConnectFlags) 0)
;
495 ctk_box_pack_start (CTK_BOX (delay_hbox)((((CtkBox*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((delay_hbox)), ((ctk_box_get_type ()))))))
, spin, FALSE(0), FALSE(0), 0);
496 ctk_label_set_mnemonic_widget (CTK_LABEL (label)((((CtkLabel*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((label)), ((ctk_label_get_type ()))))))
, spin);
497 ctk_widget_show (spin);
498
499 /* translators: this is the last part of the "grab after a
500 * delay of <spin button> seconds".
501 */
502 label = ctk_label_new (_("seconds")gettext ("seconds"));
503 ctk_label_set_xalign (CTK_LABEL (label)((((CtkLabel*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((label)), ((ctk_label_get_type ()))))))
, 0.0);
504 ctk_label_set_yalign (CTK_LABEL (label)((((CtkLabel*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((label)), ((ctk_label_get_type ()))))))
, 0.5);
505 ctk_box_pack_end (CTK_BOX (delay_hbox)((((CtkBox*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((delay_hbox)), ((ctk_box_get_type ()))))))
, label, FALSE(0), FALSE(0), 0);
506 ctk_widget_show (label);
507}
508
509static CtkWidget *
510create_interactive_dialog (void)
511{
512 CtkWidget *retval;
513 CtkWidget *main_vbox;
514 CtkWidget *content_area;
515
516 retval = ctk_dialog_new ();
517 ctk_window_set_resizable (CTK_WINDOW (retval)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((retval)), ((ctk_window_get_type ()))))))
, FALSE(0));
518 ctk_container_set_border_width (CTK_CONTAINER (retval)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((retval)), ((ctk_container_get_type ()))))))
, 5);
519 content_area = ctk_dialog_get_content_area (CTK_DIALOG (retval)((((CtkDialog*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((retval)), ((ctk_dialog_get_type ()))))))
);
520 ctk_box_set_spacing (CTK_BOX (content_area)((((CtkBox*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((content_area)), ((ctk_box_get_type ()))))))
, 2);
521 ctk_window_set_title (CTK_WINDOW (retval)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((retval)), ((ctk_window_get_type ()))))))
, _("Take Screenshot")gettext ("Take Screenshot"));
522
523 /* main container */
524 main_vbox = ctk_box_new (CTK_ORIENTATION_VERTICAL, 18);
525 ctk_container_set_border_width (CTK_CONTAINER (main_vbox)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((main_vbox)), ((ctk_container_get_type ()))))))
, 5);
526 ctk_box_pack_start (CTK_BOX (content_area)((((CtkBox*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((content_area)), ((ctk_box_get_type ()))))))
, main_vbox, TRUE(!(0)), TRUE(!(0)), 0);
527 ctk_widget_show (main_vbox);
528
529 create_screenshot_frame (main_vbox, _("Take Screenshot")gettext ("Take Screenshot"));
530 create_effects_frame (main_vbox, _("Effects")gettext ("Effects"));
531 ctk_dialog_add_buttons (CTK_DIALOG (retval)((((CtkDialog*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((retval)), ((ctk_dialog_get_type ()))))))
,
532 CTK_STOCK_HELP((CtkStock)"ctk-help"), CTK_RESPONSE_HELP,
533 CTK_STOCK_CANCEL((CtkStock)"ctk-cancel"), CTK_RESPONSE_CANCEL,
534 _("Take _Screenshot")gettext ("Take _Screenshot"), CTK_RESPONSE_OK,
535 NULL((void*)0));
536 ctk_dialog_set_default_response (CTK_DIALOG (retval)((((CtkDialog*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((retval)), ((ctk_dialog_get_type ()))))))
, CTK_RESPONSE_OK);
537
538 /* we need to block on "response" and keep showing the interactive
539 * dialog in case the user did choose "help"
540 */
541 g_signal_connect (retval, "response",g_signal_connect_data ((retval), ("response"), (((GCallback) (
interactive_dialog_response_cb))), (((void*)0)), ((void*)0), (
GConnectFlags) 0)
542 G_CALLBACK (interactive_dialog_response_cb),g_signal_connect_data ((retval), ("response"), (((GCallback) (
interactive_dialog_response_cb))), (((void*)0)), ((void*)0), (
GConnectFlags) 0)
543 NULL)g_signal_connect_data ((retval), ("response"), (((GCallback) (
interactive_dialog_response_cb))), (((void*)0)), ((void*)0), (
GConnectFlags) 0)
;
544
545 g_signal_connect (G_OBJECT (retval), "key-press-event",g_signal_connect_data ((((((GObject*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((retval)), (((GType) ((20) << (2)))
)))))), ("key-press-event"), (((GCallback) (key_press_cb))), (
((void*)0)), ((void*)0), (GConnectFlags) 0)
546 G_CALLBACK(key_press_cb),g_signal_connect_data ((((((GObject*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((retval)), (((GType) ((20) << (2)))
)))))), ("key-press-event"), (((GCallback) (key_press_cb))), (
((void*)0)), ((void*)0), (GConnectFlags) 0)
547 NULL)g_signal_connect_data ((((((GObject*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((retval)), (((GType) ((20) << (2)))
)))))), ("key-press-event"), (((GCallback) (key_press_cb))), (
((void*)0)), ((void*)0), (GConnectFlags) 0)
;
548
549 return retval;
550}
551
552static void
553save_folder_to_settings (ScreenshotDialog *dialog)
554{
555 char *folder;
556
557 folder = screenshot_dialog_get_folder (dialog);
558 g_settings_set_string (settings,
559 LAST_SAVE_DIRECTORY_KEY"last-save-directory", folder);
560
561 g_free (folder);
562}
563
564static void
565set_recent_entry (ScreenshotDialog *dialog)
566{
567 char *uri, *app_exec = NULL((void*)0);
568 CtkRecentManager *recent;
569 CtkRecentData recent_data;
570 GAppInfo *app;
571 const char *exec_name = NULL((void*)0);
572 static char * groups[2] = { "Graphics", NULL((void*)0) };
573
574 app = g_app_info_get_default_for_type ("image/png", TRUE(!(0)));
575
576 if (!app) {
577 /* return early, as this would be an useless recent entry anyway. */
578 return;
579 }
580
581 uri = screenshot_dialog_get_uri (dialog);
582 recent = ctk_recent_manager_get_default ();
583
584 exec_name = g_app_info_get_executable (app);
585 app_exec = g_strjoin (" ", exec_name, "%u", NULL((void*)0));
586
587 recent_data.display_name = NULL((void*)0);
588 recent_data.description = NULL((void*)0);
589 recent_data.mime_type = "image/png";
590 recent_data.app_name = "CAFE Screenshot";
591 recent_data.app_exec = app_exec;
592 recent_data.groups = groups;
593 recent_data.is_private = FALSE(0);
594
595 ctk_recent_manager_add_full (recent, uri, &recent_data);
596
597 g_object_unref (app);
598 g_free (app_exec);
599 g_free (uri);
600}
601
602static void
603error_dialog_response_cb (CtkDialog *d,
604 gint response,
605 ScreenshotDialog *dialog)
606{
607 ctk_widget_destroy (CTK_WIDGET (d)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((d)), ((ctk_widget_get_type ()))))))
);
608
609 screenshot_dialog_focus_entry (dialog);
610}
611
612static void
613save_callback (TransferResult result,
614 char *error_message,
615 gpointer data)
616{
617 ScreenshotDialog *dialog = data;
618 CtkWidget *toplevel;
619
620 toplevel = screenshot_dialog_get_toplevel (dialog);
621 screenshot_dialog_set_busy (dialog, FALSE(0));
622
623 if (result == TRANSFER_OK)
624 {
625 save_folder_to_settings (dialog);
626 set_recent_entry (dialog);
627 ctk_widget_destroy (toplevel);
628
629 /* we're done, stop the mainloop now */
630 ctk_main_quit ();
631 }
632 else if (result == TRANSFER_OVERWRITE ||
633 result == TRANSFER_CANCELLED)
634 {
635 /* user has canceled the overwrite dialog or the transfer itself, let him
636 * choose another name.
637 */
638 screenshot_dialog_focus_entry (dialog);
639 }
640 else /* result == TRANSFER_ERROR */
641 {
642 /* we had an error, display a dialog to the user and let him choose
643 * another name/location to save the screenshot.
644 */
645 CtkWidget *error_dialog;
646 char *uri;
647
648 uri = screenshot_dialog_get_uri (dialog);
649 error_dialog = ctk_message_dialog_new (CTK_WINDOW (toplevel)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((toplevel)), ((ctk_window_get_type ()))))))
,
650 CTK_DIALOG_DESTROY_WITH_PARENT,
651 CTK_MESSAGE_ERROR,
652 CTK_BUTTONS_OK,
653 _("Error while saving screenshot")gettext ("Error while saving screenshot"));
654 /* translators: first %s is the file path, second %s is the VFS error */
655 ctk_message_dialog_format_secondary_text (CTK_MESSAGE_DIALOG (error_dialog)((((CtkMessageDialog*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((error_dialog)), ((ctk_message_dialog_get_type
()))))))
,
656 _("Impossible to save the screenshot "gettext ("Impossible to save the screenshot " "to %s.\n Error was %s.\n Please choose another "
"location and retry.")
657 "to %s.\n Error was %s.\n Please choose another "gettext ("Impossible to save the screenshot " "to %s.\n Error was %s.\n Please choose another "
"location and retry.")
658 "location and retry.")gettext ("Impossible to save the screenshot " "to %s.\n Error was %s.\n Please choose another "
"location and retry.")
, uri, error_message);
659 ctk_widget_show (error_dialog);
660 g_signal_connect (error_dialog,g_signal_connect_data ((error_dialog), ("response"), (((GCallback
) (error_dialog_response_cb))), (dialog), ((void*)0), (GConnectFlags
) 0)
661 "response",g_signal_connect_data ((error_dialog), ("response"), (((GCallback
) (error_dialog_response_cb))), (dialog), ((void*)0), (GConnectFlags
) 0)
662 G_CALLBACK (error_dialog_response_cb),g_signal_connect_data ((error_dialog), ("response"), (((GCallback
) (error_dialog_response_cb))), (dialog), ((void*)0), (GConnectFlags
) 0)
663 dialog)g_signal_connect_data ((error_dialog), ("response"), (((GCallback
) (error_dialog_response_cb))), (dialog), ((void*)0), (GConnectFlags
) 0)
;
664
665 g_free (uri);
666 }
667
668}
669
670static void
671try_to_save (ScreenshotDialog *dialog,
672 const char *target)
673{
674 GFile *source_file, *target_file;
675
676 g_assert (temporary_file)do { if (temporary_file) ; else g_assertion_message_expr (((gchar
*) 0), "cafe-screenshot.c", 676, ((const char*) (__func__)), "temporary_file"
); } while (0)
;
677
678 screenshot_dialog_set_busy (dialog, TRUE(!(0)));
679
680 source_file = g_file_new_for_path (temporary_file);
681 target_file = g_file_new_for_uri (target);
682
683 screenshot_xfer_uri (source_file,
684 target_file,
685 screenshot_dialog_get_toplevel (dialog),
686 save_callback, dialog);
687
688 /* screenshot_xfer_uri () holds a ref, so we can unref now */
689 g_object_unref (source_file);
690 g_object_unref (target_file);
691}
692
693static void
694save_done_notification (gpointer data)
695{
696 ScreenshotDialog *dialog = data;
697
698 temporary_file = g_strdup (screenshot_save_get_filename ())g_strdup_inline (screenshot_save_get_filename ());
699 screenshot_dialog_enable_dnd (dialog);
700
701 if (save_immediately)
702 {
703 CtkWidget *toplevel;
704
705 toplevel = screenshot_dialog_get_toplevel (dialog);
706 ctk_dialog_response (CTK_DIALOG (toplevel)((((CtkDialog*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((toplevel)), ((ctk_dialog_get_type ()))))))
, CTK_RESPONSE_OK);
707 }
708}
709
710static void
711save_screenshot_in_clipboard (CdkDisplay *display, GdkPixbuf *screenshot)
712{
713 CtkClipboard *clipboard =
714 ctk_clipboard_get_for_display (display, CDK_SELECTION_CLIPBOARD((CdkAtom)((gpointer) (gulong) (69))));
715 ctk_clipboard_set_image (clipboard, screenshot);
716}
717
718static void
719screenshot_dialog_response_cb (CtkDialog *d,
720 gint response_id,
721 ScreenshotDialog *dialog)
722{
723 char *uri;
724
725 if (response_id == CTK_RESPONSE_HELP)
726 {
727 display_help (CTK_WINDOW (d)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((d)), ((ctk_window_get_type ()))))))
);
728 }
729 else if (response_id == SCREENSHOT_RESPONSE_NEW22)
730 {
731 ctk_widget_destroy (CTK_WIDGET (d)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((d)), ((ctk_widget_get_type ()))))))
);
732 ctk_main_quit ();
733 interactive_arg = TRUE(!(0));
734 loop_dialog_screenshot();
735 }
736 else if (response_id == CTK_RESPONSE_OK)
737 {
738 uri = screenshot_dialog_get_uri (dialog);
739 if (temporary_file == NULL((void*)0))
740 {
741 save_immediately = TRUE(!(0));
742 screenshot_dialog_set_busy (dialog, TRUE(!(0)));
743 }
744 else
745 {
746 /* we've saved the temporary file, lets try to copy it to the
747 * correct location.
748 */
749 try_to_save (dialog, uri);
750 }
751 g_free (uri);
752 }
753 else if (response_id == SCREENSHOT_RESPONSE_COPY1)
754 {
755 save_screenshot_in_clipboard (ctk_widget_get_display (CTK_WIDGET (d)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((d)), ((ctk_widget_get_type ()))))))
),
756 screenshot_dialog_get_screenshot (dialog));
757 }
758 else /* dialog was canceled */
759 {
760 ctk_widget_destroy (CTK_WIDGET (d)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((d)), ((ctk_widget_get_type ()))))))
);
761 ctk_main_quit ();
762 }
763}
764
765
766static void
767run_dialog (ScreenshotDialog *dialog)
768{
769 CtkWidget *toplevel;
770
771 toplevel = screenshot_dialog_get_toplevel (dialog);
772
773 ctk_widget_show (toplevel);
774
775 g_signal_connect (toplevel,g_signal_connect_data ((toplevel), ("response"), (((GCallback
) (screenshot_dialog_response_cb))), (dialog), ((void*)0), (GConnectFlags
) 0)
776 "response",g_signal_connect_data ((toplevel), ("response"), (((GCallback
) (screenshot_dialog_response_cb))), (dialog), ((void*)0), (GConnectFlags
) 0)
777 G_CALLBACK (screenshot_dialog_response_cb),g_signal_connect_data ((toplevel), ("response"), (((GCallback
) (screenshot_dialog_response_cb))), (dialog), ((void*)0), (GConnectFlags
) 0)
778 dialog)g_signal_connect_data ((toplevel), ("response"), (((GCallback
) (screenshot_dialog_response_cb))), (dialog), ((void*)0), (GConnectFlags
) 0)
;
779}
780
781static void
782play_sound_effect (CdkWindow *window)
783{
784 ka_context *c;
785 ka_proplist *p = NULL((void*)0);
786 int res;
787
788 c = ka_ctk_context_get ();
789
790 res = ka_proplist_create (&p);
791 if (res < 0)
792 goto done;
793
794 res = ka_proplist_sets (p, KA_PROP_EVENT_ID"event.id", "screen-capture");
795 if (res < 0)
796 goto done;
797
798 res = ka_proplist_sets (p, KA_PROP_EVENT_DESCRIPTION"event.description", _("Screenshot taken")gettext ("Screenshot taken"));
799 if (res < 0)
800 goto done;
801
802 if (window != NULL((void*)0))
803 {
804 res = ka_proplist_setf (p,
805 KA_PROP_WINDOW_X11_XID"window.x11.xid",
806 "%lu",
807 (unsigned long) CDK_WINDOW_XID (window)(cdk_x11_window_get_xid (window)));
808 if (res < 0)
809 goto done;
810 }
811
812 ka_context_play_full (c, 0, p, NULL((void*)0), NULL((void*)0));
813
814 done:
815 if (p != NULL((void*)0))
816 ka_proplist_destroy (p);
817
818}
819
820static void
821finish_prepare_screenshot (char *initial_uri, CdkWindow *window, CdkRectangle *rectangle)
822{
823 ScreenshotDialog *dialog;
824 gboolean include_mask = (!take_window_shot && !take_area_shot);
825
826 /* always disable window border for full-desktop or selected-area screenshots */
827 if (!take_window_shot)
828 screenshot = screenshot_get_pixbuf (window, rectangle, include_pointer, FALSE(0), include_mask);
829 else
830 {
831 screenshot = screenshot_get_pixbuf (window, rectangle, include_pointer, include_border, include_mask);
832
833 switch (border_effect[0])
834 {
835 case 's': /* shadow */
836 screenshot_add_shadow (&screenshot);
837 break;
838 case 'b': /* border */
839 screenshot_add_border (&screenshot);
840 break;
841 case 'n': /* none */
842 default:
843 break;
844 }
845 }
846
847 /* release now the lock, it was acquired when we were finding the window */
848 screenshot_release_lock ();
849
850 if (screenshot == NULL((void*)0))
851 {
852 screenshot_show_error_dialog (NULL((void*)0),
853 _("Unable to take a screenshot of the current window")gettext ("Unable to take a screenshot of the current window"),
854 NULL((void*)0));
855 exit (1);
856 }
857
858 play_sound_effect (window);
859
860 if (noninteractive_clipboard_arg) {
861 save_screenshot_in_clipboard (cdk_window_get_display (window), screenshot);
862 g_free (initial_uri);
863 /* Done here: */
864 ctk_main_quit ();
865 return;
866 }
867
868 dialog = screenshot_dialog_new (screenshot, initial_uri, take_window_shot);
869 g_free (initial_uri);
870
871 screenshot_save_start (screenshot, save_done_notification, dialog);
872
873 run_dialog (dialog);
874}
875
876static void
877async_existence_job_free (AsyncExistenceJob *job)
878{
879 if (!job)
880 return;
881
882 g_free (job->base_uris[1]);
883 g_free (job->base_uris[2]);
884
885 if (job->rectangle != NULL((void*)0))
886 g_slice_free (CdkRectangle, job->rectangle)do { if (1) g_slice_free1 (sizeof (CdkRectangle), (job->rectangle
)); else (void) ((CdkRectangle*) 0 == (job->rectangle)); }
while (0)
;
887
888 g_slice_free (AsyncExistenceJob, job)do { if (1) g_slice_free1 (sizeof (AsyncExistenceJob), (job))
; else (void) ((AsyncExistenceJob*) 0 == (job)); } while (0)
;
889}
890
891static gboolean
892check_file_done (gpointer user_data)
893{
894 AsyncExistenceJob *job = user_data;
895
896 finish_prepare_screenshot (job->retval, job->window, job->rectangle);
897
898 async_existence_job_free (job);
899
900 return FALSE(0);
901}
902
903static char *
904build_uri (AsyncExistenceJob *job)
905{
906 char *retval, *file_name;
907 char *timestamp;
908 GDateTime *d;
909
910 d = g_date_time_new_now_local ();
911 timestamp = g_date_time_format (d, "%Y-%m-%d %H-%M-%S");
912 g_date_time_unref (d);
913
914 if (job->iteration
22.1
Field 'iteration' is equal to 0
== 0)
23
Taking true branch
915 {
916 /* translators: this is the name of the file that gets made up
917 * with the screenshot if the entire screen is taken */
918 file_name = g_strdup_printf (_("Screenshot at %s.png")gettext ("Screenshot at %s.png"), timestamp);
919 }
920 else
921 {
922 /* translators: this is the name of the file that gets
923 * made up with the screenshot if the entire screen is
924 * taken */
925 file_name = g_strdup_printf (_("Screenshot at %s - %d.png")gettext ("Screenshot at %s - %d.png"), timestamp, job->iteration);
926 }
927
928 retval = g_build_filename (job->base_uris[job->type], file_name, NULL((void*)0));
24
Access of the field 'base_uris' at index 3, while it holds only 3 'char *' elements
929 g_free (file_name);
930 g_free (timestamp);
931
932 return retval;
933}
934
935static gboolean
936try_check_file (GIOSchedulerJob *io_job,
937 GCancellable *cancellable,
938 gpointer data)
939{
940 AsyncExistenceJob *job = data;
941 GFile *file;
942 GFileInfo *info;
943 GError *error;
944 char *uri;
945
946retry:
947 error = NULL((void*)0);
948 uri = build_uri (job);
22
Calling 'build_uri'
949 file = g_file_new_for_uri (uri);
950
951 info = g_file_query_info (file, G_FILE_ATTRIBUTE_STANDARD_TYPE"standard::type",
952 G_FILE_QUERY_INFO_NONE, cancellable, &error);
953 if (info != NULL((void*)0))
1
Assuming 'info' is equal to NULL
2
Taking false branch
8
Assuming 'info' is equal to NULL
9
Taking false branch
15
Assuming 'info' is equal to NULL
16
Taking false branch
954 {
955 /* file already exists, iterate again */
956 g_object_unref (info);
957 g_object_unref (file);
958 g_free (uri);
959
960 (job->iteration)++;
961
962 goto retry;
963 }
964 else
965 {
966 /* see the error to check whether the location is not accessible
967 * or the file does not exist.
968 */
969 if (error->code == G_IO_ERROR_NOT_FOUND)
3
Assuming field 'code' is not equal to G_IO_ERROR_NOT_FOUND
4
Taking false branch
10
Assuming field 'code' is not equal to G_IO_ERROR_NOT_FOUND
11
Taking false branch
17
Assuming field 'code' is equal to G_IO_ERROR_NOT_FOUND
18
Taking true branch
970 {
971 GFile *parent;
972
973 /* if the parent directory doesn't exist as well, forget the saved
974 * directory and treat this as a generic error.
975 */
976
977 parent = g_file_get_parent (file);
978
979 if (!g_file_query_exists (parent, NULL((void*)0)))
19
Assuming the condition is true
20
Taking true branch
980 {
981 (job->type)++;
982 job->iteration = 0;
983
984 g_object_unref (file);
985 g_object_unref (parent);
986 goto retry;
21
Control jumps to line 947
987 }
988 else
989 {
990 job->retval = uri;
991
992 g_object_unref (parent);
993 goto out;
994 }
995 }
996 else
997 {
998 /* another kind of error, assume this location is not
999 * accessible.
1000 */
1001 g_free (uri);
1002 if (job->type == TEST_TMP)
5
Assuming field 'type' is not equal to TEST_TMP
6
Taking false branch
12
Assuming field 'type' is not equal to TEST_TMP
13
Taking false branch
1003 {
1004 job->retval = NULL((void*)0);
1005 goto out;
1006 }
1007 else
1008 {
1009 (job->type)++;
1010 job->iteration = 0;
1011
1012 g_error_free (error);
1013 g_object_unref (file);
1014 goto retry;
7
Control jumps to line 947
14
Control jumps to line 947
1015 }
1016 }
1017 }
1018
1019out:
1020 g_error_free (error);
1021 g_object_unref (file);
1022
1023 g_io_scheduler_job_send_to_mainloop_async (io_job,
1024 check_file_done,
1025 job,
1026 NULL((void*)0));
1027 return FALSE(0);
1028}
1029
1030static CdkWindow *
1031find_current_window (void)
1032{
1033 CdkWindow *window;
1034
1035 if (!screenshot_grab_lock ())
1036 exit (0);
1037
1038 if (take_window_shot)
1039 {
1040 window = screenshot_find_current_window ();
1041 if (!window)
1042 {
1043 take_window_shot = FALSE(0);
1044 window = cdk_get_default_root_window ();
1045 }
1046 }
1047 else
1048 {
1049 window = cdk_get_default_root_window ();
1050 }
1051
1052 return window;
1053}
1054
1055static void
1056push_check_file_job (CdkRectangle *rectangle)
1057{
1058 AsyncExistenceJob *job;
1059
1060 job = g_slice_new0 (AsyncExistenceJob)((AsyncExistenceJob*) g_slice_alloc0 (sizeof (AsyncExistenceJob
)))
;
1061 job->base_uris[0] = last_save_dir;
1062 /* we'll have to free these two */
1063 job->base_uris[1] = get_desktop_dir ();
1064 job->base_uris[2] = g_strconcat ("file://", g_get_tmp_dir (), NULL((void*)0));
1065 job->iteration = 0;
1066 job->type = TEST_LAST_DIR;
1067 job->window = find_current_window ();
1068
1069 if (rectangle != NULL((void*)0))
1070 {
1071 job->rectangle = g_slice_new0 (CdkRectangle)((CdkRectangle*) g_slice_alloc0 (sizeof (CdkRectangle)));
1072 job->rectangle->x = rectangle->x;
1073 job->rectangle->y = rectangle->y;
1074 job->rectangle->width = rectangle->width;
1075 job->rectangle->height = rectangle->height;
1076 }
1077
1078 /* Check if the area selection was cancelled */
1079 if (job->rectangle &&
1080 (job->rectangle->width == 0 || job->rectangle->height == 0))
1081 {
1082 async_existence_job_free (job);
1083 ctk_main_quit ();
1084 return;
1085 }
1086
1087 g_io_scheduler_push_job (try_check_file,
1088 job,
1089 NULL((void*)0),
1090 0, NULL((void*)0));
1091
1092}
1093
1094static void
1095rectangle_found_cb (CdkRectangle *rectangle)
1096{
1097 push_check_file_job (rectangle);
1098}
1099
1100static void
1101prepare_screenshot (void)
1102{
1103 if (take_area_shot)
1104 screenshot_select_area_async (rectangle_found_cb);
1105 else
1106 push_check_file_job (NULL((void*)0));
1107}
1108
1109static gboolean
1110prepare_screenshot_timeout (gpointer data)
1111{
1112 prepare_screenshot ();
1113 save_options ();
1114
1115 return FALSE(0);
1116}
1117
1118
1119static gchar *
1120get_desktop_dir (void)
1121{
1122 gboolean desktop_is_home_dir = FALSE(0);
1123 gchar *desktop_dir;
1124
1125 /* Check if baul schema is installed before trying to read settings */
1126 GSettingsSchema *schema = g_settings_schema_source_lookup (g_settings_schema_source_get_default (),
1127 BAUL_PREFERENCES_SCHEMA"org.cafe.baul.preferences",
1128 FALSE(0));
1129
1130 if (schema != NULL((void*)0)) {
1131 GSettings *baul_prefs;
1132
1133 baul_prefs = g_settings_new (BAUL_PREFERENCES_SCHEMA"org.cafe.baul.preferences");
1134 desktop_is_home_dir = g_settings_get_boolean (baul_prefs, "desktop-is-home-dir");
1135
1136 g_object_unref (baul_prefs);
1137 g_settings_schema_unref (schema);
1138 }
1139
1140 if (desktop_is_home_dir)
1141 desktop_dir = g_strconcat ("file://", g_get_home_dir (), NULL((void*)0));
1142 else
1143 desktop_dir = g_strconcat ("file://", g_get_user_special_dir (G_USER_DIRECTORY_DESKTOP), NULL((void*)0));
1144
1145 return desktop_dir;
1146}
1147
1148/* Taken from cafe-vfs-utils.c */
1149static char *
1150expand_initial_tilde (const char *path)
1151{
1152 char *slash_after_user_name, *user_name;
1153 struct passwd *passwd_file_entry;
1154
1155 if (path[1] == '/' || path[1] == '\0') {
1156 return g_strconcat (g_get_home_dir (), &path[1], NULL((void*)0));
1157 }
1158
1159 slash_after_user_name = strchr (&path[1], '/');
1160 if (slash_after_user_name == NULL((void*)0)) {
1161 user_name = g_strdup (&path[1])g_strdup_inline (&path[1]);
1162 } else {
1163 user_name = g_strndup (&path[1],
1164 slash_after_user_name - &path[1]);
1165 }
1166 passwd_file_entry = getpwnam (user_name);
1167 g_free (user_name);
1168
1169 if (passwd_file_entry == NULL((void*)0) || passwd_file_entry->pw_dir == NULL((void*)0)) {
1170 return g_strdup (path)g_strdup_inline (path);
1171 }
1172
1173 return g_strconcat (passwd_file_entry->pw_dir,
1174 slash_after_user_name,
1175 NULL((void*)0));
1176}
1177
1178/* Load options */
1179static void
1180load_options (void)
1181{
1182 /* Find various dirs */
1183 last_save_dir = g_settings_get_string (settings,
1184 LAST_SAVE_DIRECTORY_KEY"last-save-directory");
1185 if (!last_save_dir || !last_save_dir[0])
1186 {
1187 last_save_dir = get_desktop_dir ();
1188 }
1189 else if (last_save_dir[0] == '~')
1190 {
1191 char *tmp = expand_initial_tilde (last_save_dir);
1192 g_free (last_save_dir);
1193 last_save_dir = tmp;
1194 }
1195
1196 include_border = g_settings_get_boolean (settings,
1197 INCLUDE_BORDER_KEY"include-border");
1198
1199 include_pointer = g_settings_get_boolean (settings,
1200 INCLUDE_POINTER_KEY"include-pointer");
1201
1202 border_effect = g_settings_get_string (settings,
1203 BORDER_EFFECT_KEY"border-effect");
1204 if (!border_effect)
1205 border_effect = g_strdup ("none")g_strdup_inline ("none");
1206
1207 delay = g_settings_get_int (settings, DELAY_KEY"delay");
1208}
1209
1210static void
1211save_options (void)
1212{
1213 g_settings_set_boolean (settings,
1214 INCLUDE_BORDER_KEY"include-border", include_border);
1215 g_settings_set_boolean (settings,
1216 INCLUDE_POINTER_KEY"include-pointer", include_pointer);
1217 g_settings_set_int (settings, DELAY_KEY"delay", delay);
1218 g_settings_set_string (settings,
1219 BORDER_EFFECT_KEY"border-effect", border_effect);
1220}
1221
1222
1223static void
1224register_screenshooter_icon (CtkIconFactory * factory)
1225{
1226 CtkIconSource *source;
1227 CtkIconSet *icon_set;
1228
1229 source = ctk_icon_source_new ();
1230 ctk_icon_source_set_icon_name (source, SCREENSHOOTER_ICON"applets-screenshooter");
1231
1232 icon_set = ctk_icon_set_new ();
1233 ctk_icon_set_add_source (icon_set, source);
1234
1235 ctk_icon_factory_add (factory, SCREENSHOOTER_ICON"applets-screenshooter", icon_set);
1236 ctk_icon_set_unref (icon_set);
1237 ctk_icon_source_free (source);
1238}
1239
1240static void
1241screenshooter_init_stock_icons (void)
1242{
1243 CtkIconFactory *factory;
1244
1245 factory = ctk_icon_factory_new ();
1246 ctk_icon_factory_add_default (factory);
1247
1248 register_screenshooter_icon (factory);
1249 g_object_unref (factory);
1250}
1251
1252void
1253loop_dialog_screenshot ()
1254{
1255 /* interactive mode overrides everything */
1256 if (interactive_arg)
1257 {
1258 CtkWidget *dialog;
1259 gint response;
1260
1261 dialog = create_interactive_dialog ();
1262 response = ctk_dialog_run (CTK_DIALOG (dialog)((((CtkDialog*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog)), ((ctk_dialog_get_type ()))))))
);
1263 ctk_widget_destroy (dialog);
1264
1265 switch (response)
1266 {
1267 case CTK_RESPONSE_DELETE_EVENT:
1268 case CTK_RESPONSE_CANCEL:
1269 return;
1270 case CTK_RESPONSE_OK:
1271 break;
1272 default:
1273 g_assert_not_reached ()do { g_assertion_message_expr (((gchar*) 0), "cafe-screenshot.c"
, 1273, ((const char*) (__func__)), ((void*)0)); } while (0)
;
1274 break;
1275 }
1276 }
1277
1278 if (((delay > 0 && interactive_arg) || delay_arg > 0) &&
1279 !take_area_shot)
1280 {
1281 g_timeout_add (delay * 1000,
1282 prepare_screenshot_timeout,
1283 NULL((void*)0));
1284 }
1285 else
1286 {
1287 if (interactive_arg)
1288 {
1289 /* HACK: give time to the dialog to actually disappear.
1290 * We don't have any way to tell when the compositor has finished
1291 * re-drawing.
1292 */
1293 g_timeout_add (200,
1294 prepare_screenshot_timeout, NULL((void*)0));
1295 }
1296 else
1297 g_idle_add (prepare_screenshot_timeout, NULL((void*)0));
1298 }
1299
1300 ctk_main ();
1301}
1302
1303static gboolean
1304signal_handler (gpointer data)
1305{
1306 /* exit cleanly on signals to allow cleaning up temporary files */
1307 ctk_main_quit ();
1308 return FALSE(0);
1309}
1310
1311/* main */
1312int
1313main (int argc, char *argv[])
1314{
1315 GOptionContext *context;
1316 gboolean window_arg = FALSE(0);
1317 gboolean area_arg = FALSE(0);
1318 gboolean include_border_arg = FALSE(0);
1319 gboolean disable_border_arg = FALSE(0);
1320 gchar *border_effect_arg = NULL((void*)0);
1321 gboolean version_arg = FALSE(0);
1322 GError *error = NULL((void*)0);
1323
1324 const GOptionEntry entries[] = {
1325 { "window", 'w', 0, G_OPTION_ARG_NONE, &window_arg, N_("Grab a window instead of the entire screen")("Grab a window instead of the entire screen"), NULL((void*)0) },
1326 { "area", 'a', 0, G_OPTION_ARG_NONE, &area_arg, N_("Grab an area of the screen instead of the entire screen")("Grab an area of the screen instead of the entire screen"), NULL((void*)0) },
1327 { "clipboard", 'c', 0, G_OPTION_ARG_NONE, &noninteractive_clipboard_arg, N_("Send grabbed area directly to the clipboard")("Send grabbed area directly to the clipboard"), NULL((void*)0) },
1328 { "include-border", 'b', 0, G_OPTION_ARG_NONE, &include_border_arg, N_("Include the window border with the screenshot")("Include the window border with the screenshot"), NULL((void*)0) },
1329 { "remove-border", 'B', 0, G_OPTION_ARG_NONE, &disable_border_arg, N_("Remove the window border from the screenshot")("Remove the window border from the screenshot"), NULL((void*)0) },
1330 { "delay", 'd', 0, G_OPTION_ARG_INT, &delay_arg, N_("Take screenshot after specified delay [in seconds]")("Take screenshot after specified delay [in seconds]"), N_("seconds")("seconds") },
1331 { "border-effect", 'e', 0, G_OPTION_ARG_STRING, &border_effect_arg, N_("Effect to add to the border (shadow, border or none)")("Effect to add to the border (shadow, border or none)"), N_("effect")("effect") },
1332 { "interactive", 'i', 0, G_OPTION_ARG_NONE, &interactive_arg, N_("Interactively set options")("Interactively set options"), NULL((void*)0) },
1333 { "version", 0, 0, G_OPTION_ARG_NONE, &version_arg, N_("Print version information and exit")("Print version information and exit"), NULL((void*)0) },
1334 { NULL((void*)0) },
1335 };
1336
1337 setlocale (LC_ALL6, "");
1338 bindtextdomain (GETTEXT_PACKAGE"cafe-utils", CAFELOCALEDIR"/usr/share/locale");
1339 bind_textdomain_codeset (GETTEXT_PACKAGE"cafe-utils", "UTF-8");
1340 textdomain (GETTEXT_PACKAGE"cafe-utils");
1341
1342 context = g_option_context_new (_("Take a picture of the screen")gettext ("Take a picture of the screen"));
1343 g_option_context_set_ignore_unknown_options (context, FALSE(0));
1344 g_option_context_set_help_enabled (context, TRUE(!(0)));
1345 g_option_context_add_main_entries (context, entries, GETTEXT_PACKAGE"cafe-utils");
1346 g_option_context_add_group (context, ctk_get_option_group (TRUE(!(0))));
1347
1348 g_option_context_parse (context, &argc, &argv, &error);
1349
1350 if (error) {
1351 g_critical ("Unable to parse arguments: %s", error->message);
1352 g_error_free (error);
1353 g_option_context_free (context);
1354 exit (1);
1355 }
1356
1357 g_option_context_free (context);
1358
1359 if (version_arg) {
1360 g_print ("%s %s\n", g_get_application_name (), VERSION"1.25.0");
1361 exit (EXIT_SUCCESS0);
1362 }
1363
1364 if (interactive_arg && noninteractive_clipboard_arg) {
1365 g_printerr (_("Conflicting options: --clipboard and --interactive should not be "gettext ("Conflicting options: --clipboard and --interactive should not be "
"used at the same time.\n")
1366 "used at the same time.\n")gettext ("Conflicting options: --clipboard and --interactive should not be "
"used at the same time.\n")
);
1367 exit (1);
1368 }
1369
1370 if (window_arg && area_arg) {
1371 g_printerr (_("Conflicting options: --window and --area should not be "gettext ("Conflicting options: --window and --area should not be "
"used at the same time.\n")
1372 "used at the same time.\n")gettext ("Conflicting options: --window and --area should not be "
"used at the same time.\n")
);
1373 exit (1);
1374 }
1375
1376 ctk_window_set_default_icon_name (SCREENSHOOTER_ICON"applets-screenshooter");
1377
1378 g_object_set (ctk_settings_get_default (), "ctk-button-images", TRUE(!(0)), NULL((void*)0));
1379
1380 screenshooter_init_stock_icons ();
1381
1382 settings = g_settings_new (CAFE_SCREENSHOT_SCHEMA"org.cafe.screenshot");
1383 load_options ();
1384 /* allow the command line to override options */
1385 if (window_arg)
1386 take_window_shot = TRUE(!(0));
1387
1388 if (area_arg)
1389 take_area_shot = TRUE(!(0));
1390
1391 if (include_border_arg)
1392 include_border = TRUE(!(0));
1393
1394 if (disable_border_arg)
1395 include_border = FALSE(0);
1396
1397 if (border_effect_arg)
1398 {
1399 g_free (border_effect);
1400 border_effect = border_effect_arg;
1401 }
1402
1403 if (delay_arg > 0)
1404 delay = delay_arg;
1405
1406 g_unix_signal_add (SIGINT2, signal_handler, NULL((void*)0));
1407 g_unix_signal_add (SIGTERM15, signal_handler, NULL((void*)0));
1408
1409 loop_dialog_screenshot();
1410
1411 return EXIT_SUCCESS0;
1412}