Bug Summary

File:cafe-screenshot/src/cafe-screenshot.c
Warning:line 926, column 30
Out of bound memory access (access exceeds upper limit of memory block)

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