Bug Summary

File:applets/fish/fish.c
Warning:line 1583, column 3
This statement is never executed

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 fish.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/applets/fish -resource-dir /usr/lib/llvm-16/lib/clang/16 -D HAVE_CONFIG_H -I . -I ../.. -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/sysprof-6 -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/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/sysprof-6 -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/cafe-desktop-2.0 -I /usr/include/startup-notification-1.0 -I /usr/include/dconf -I . -I ./../../libcafe-panel-applet -I ../../libcafe-panel-applet -D CAFELOCALEDIR="/usr/share/locale" -D FISH_ICONDIR="/usr/share/cafe-panel/fish" -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/applets/fish -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/2024-07-14-145726-56037-1 -x c fish.c
1/* fish.c:
2 *
3 * Copyright (C) 1998-2002 Free Software Foundation, Inc.
4 * Copyright (C) 2002-2005 Vincent Untz
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor,
19 * Boston, MA 02110-1301, USA.
20 *
21 * Authors:
22 * George Lebl <jirka@5z.com>
23 * Mark McLoughlin <mark@skynet.ie>
24 * Vincent Untz <vuntz@gnome.org>
25 * Stefano Karapetsas <stefano@karapetsas.com>
26 */
27
28#include <config.h>
29
30#include <math.h>
31#include <string.h>
32#include <time.h>
33
34#include <cairo.h>
35
36#include <glib/gi18n.h>
37#include <glib-object.h>
38#include <ctk/ctk.h>
39#include <cdk/cdkkeysyms.h>
40#include <gio/gio.h>
41
42#include <cafe-panel-applet.h>
43#include <cafe-panel-applet-gsettings.h>
44
45#define FISH_APPLET(o)((((FishApplet*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((o)), (fish_applet_get_type())))))
\
46 (G_TYPE_CHECK_INSTANCE_CAST((o), fish_applet_get_type(), FishApplet)(((FishApplet*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((o)), (fish_applet_get_type()))))
)
47#define FISH_IS_APPLET(o)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(o)); GType __t = (FISH_TYPE_APPLET); gboolean __r; if (!__inst
) __r = (0); else if (__inst->g_class && __inst->
g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a
(__inst, __t); __r; }))))
\
48 (G_TYPE_CHECK_INSTANCE_TYPE((o), FISH_TYPE_APPLET)((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(o)); GType __t = (FISH_TYPE_APPLET); gboolean __r; if (!__inst
) __r = (0); else if (__inst->g_class && __inst->
g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a
(__inst, __t); __r; })))
)
49
50#define FISH_ICON"cafe-panel-fish" "cafe-panel-fish"
51#define FISH_RESOURCE_PATH"/org/cafe/panel/applet/fish/" "/org/cafe/panel/applet/fish/"
52
53#define FISH_SCHEMA"org.cafe.panel.applet.fish" "org.cafe.panel.applet.fish"
54#define FISH_NAME_KEY"name" "name"
55#define FISH_IMAGE_KEY"image" "image"
56#define FISH_COMMAND_KEY"command" "command"
57#define FISH_FRAMES_KEY"frames" "frames"
58#define FISH_SPEED_KEY"speed" "speed"
59#define FISH_ROTATE_KEY"rotate" "rotate"
60
61#define LOCKDOWN_SCHEMA"org.cafe.lockdown" "org.cafe.lockdown"
62#define LOCKDOWN_DISABLE_COMMAND_LINE_KEY"disable-command-line" "disable-command-line"
63
64typedef struct {
65 CafePanelApplet applet;
66
67 GSettings *settings;
68 GSettings *lockdown_settings;
69
70 char *name;
71 char *image;
72 char *command;
73 int n_frames;
74 gdouble speed;
75 gboolean rotate;
76
77 CafePanelAppletOrient orientation;
78
79 CtkWidget *frame;
80 CtkWidget *drawing_area;
81 CtkRequisition requisition;
82 CdkRectangle prev_allocation;
83 cairo_surface_t *surface;
84 gint surface_width;
85 gint surface_height;
86
87 guint timeout;
88 int current_frame;
89 gboolean in_applet;
90
91 GdkPixbuf *pixbuf;
92
93 CtkWidget *preferences_dialog;
94 CtkWidget *name_entry;
95 CtkWidget *command_label;
96 CtkWidget *command_entry;
97 CtkWidget *preview_image;
98 CtkWidget *image_chooser;
99 CtkWidget *frames_spin;
100 CtkWidget *speed_spin;
101 CtkWidget *rotate_toggle;
102
103 CtkWidget *fortune_dialog;
104 CtkWidget *fortune_view;
105 CtkWidget *fortune_label;
106 CtkWidget *fortune_cmd_label;
107 CtkTextBuffer *fortune_buffer;
108
109 unsigned int source_id;
110 GIOChannel *io_channel;
111
112 gboolean april_fools;
113} FishApplet;
114
115typedef struct {
116 CafePanelAppletClass klass;
117} FishAppletClass;
118
119
120static gboolean load_fish_image (FishApplet *fish);
121static void update_pixmap (FishApplet *fish);
122static void something_fishy_going_on (FishApplet *fish, const char *message);
123static void display_fortune_dialog (FishApplet *fish);
124static void set_tooltip (FishApplet *fish);
125
126static GType fish_applet_get_type (void);
127
128static GObjectClass *parent_class;
129
130static int fools_day = 0;
131static int fools_month = 0;
132static int fools_hour_start = 0;
133static int fools_hour_end = 0;
134
135static char* get_image_path(FishApplet* fish)
136{
137 char *path;
138
139 if (g_path_is_absolute (fish->image))
140 path = g_strdup (fish->image)g_strdup_inline (fish->image);
141 else
142 path = g_strdup_printf ("%s/%s", FISH_ICONDIR"/usr/share/cafe-panel/fish", fish->image);
143
144 return path;
145}
146
147static void show_help(FishApplet* fish, const char* link_id)
148{
149 GError *error = NULL((void*)0);
150 char *uri;
151#define FISH_HELP_DOC"cafe-fish" "cafe-fish"
152
153 if (link_id)
154 uri = g_strdup_printf ("help:%s/%s", FISH_HELP_DOC"cafe-fish", link_id);
155 else
156 uri = g_strdup_printf ("help:%s", FISH_HELP_DOC"cafe-fish");
157
158 ctk_show_uri_on_window (NULL((void*)0), uri,
159 ctk_get_current_event_time (), &error);
160 g_free (uri);
161
162 if (error &&
163 g_error_matches (error, G_IO_ERRORg_io_error_quark(), G_IO_ERROR_CANCELLED))
164 g_error_free (error);
165 else if (error) {
166 CtkWidget *dialog;
167 char *primary;
168
169 primary = g_markup_printf_escaped (
170 _("Could not display help document '%s'")gettext ("Could not display help document '%s'"),
171 FISH_HELP_DOC"cafe-fish");
172 dialog = ctk_message_dialog_new (
173 NULL((void*)0),
174 CTK_DIALOG_DESTROY_WITH_PARENT,
175 CTK_MESSAGE_ERROR,
176 CTK_BUTTONS_CLOSE,
177 "%s", primary);
178
179 ctk_message_dialog_format_secondary_text (
180 CTK_MESSAGE_DIALOG (dialog)((((CtkMessageDialog*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((dialog)), ((ctk_message_dialog_get_type ())
)))))
,
181 "%s", error->message);
182
183 g_error_free (error);
184 g_free (primary);
185
186 g_signal_connect (dialog, "response",g_signal_connect_data ((dialog), ("response"), (((GCallback) (
ctk_widget_destroy))), (((void*)0)), ((void*)0), (GConnectFlags
) 0)
187 G_CALLBACK (ctk_widget_destroy),g_signal_connect_data ((dialog), ("response"), (((GCallback) (
ctk_widget_destroy))), (((void*)0)), ((void*)0), (GConnectFlags
) 0)
188 NULL)g_signal_connect_data ((dialog), ("response"), (((GCallback) (
ctk_widget_destroy))), (((void*)0)), ((void*)0), (GConnectFlags
) 0)
;
189
190 ctk_window_set_icon_name (CTK_WINDOW (dialog)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog)), ((ctk_window_get_type ()))))))
, FISH_ICON"cafe-panel-fish");
191 ctk_window_set_screen (CTK_WINDOW (dialog)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog)), ((ctk_window_get_type ()))))))
,
192 ctk_widget_get_screen (CTK_WIDGET (fish)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((fish)), ((ctk_widget_get_type ()))))))
));
193 /* we have no parent window */
194 ctk_window_set_skip_taskbar_hint (CTK_WINDOW (dialog)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog)), ((ctk_window_get_type ()))))))
, FALSE(0));
195 ctk_window_set_title (CTK_WINDOW (dialog)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog)), ((ctk_window_get_type ()))))))
,
196 _("Error displaying help document")gettext ("Error displaying help document"));
197
198 ctk_widget_show (dialog);
199 }
200}
201
202static void name_value_changed(CtkEntry* entry, FishApplet* fish)
203{
204 const char *text;
205
206 text = ctk_entry_get_text (entry);
207
208 if (!text || !text [0])
209 return;
210
211 g_settings_set_string (fish->settings, FISH_NAME_KEY"name", text);
212}
213
214static void image_value_changed(CtkFileChooser* chooser, FishApplet* fish)
215{ char *path;
216 char *image;
217 char *path_gsettings;
218
219 path = ctk_file_chooser_get_filename (CTK_FILE_CHOOSER (chooser)((((CtkFileChooser*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((chooser)), ((ctk_file_chooser_get_type ()))))))
);
220
221 if (!path || !path[0]) {
222 g_free (path);
223 return;
224 }
225
226 path_gsettings = get_image_path (fish);
227 if (!strcmp (path, path_gsettings)) {
228 g_free (path);
229 g_free (path_gsettings);
230 return;
231 }
232 g_free (path_gsettings);
233
234 if (!strncmp (path, FISH_ICONDIR"/usr/share/cafe-panel/fish", strlen (FISH_ICONDIR"/usr/share/cafe-panel/fish"))) {
235 image = path + strlen (FISH_ICONDIR"/usr/share/cafe-panel/fish");
236 while (*image && *image == G_DIR_SEPARATOR'/')
237 image++;
238 } else
239 image = path;
240
241 g_settings_set_string (fish->settings, FISH_IMAGE_KEY"image", image);
242
243 g_free (path);
244}
245
246static void command_value_changed(CtkEntry* entry, FishApplet *fish)
247{
248 const char *text;
249
250 text = ctk_entry_get_text (entry);
251
252 if (!text || !text [0]) {
253 g_settings_set_string (fish->settings, FISH_COMMAND_KEY"command", "");
254 return;
255 }
256
257 if (!strncmp (text, "ps ", 3) ||
258 !strcmp (text, "ps") ||
259 !strncmp (text, "who ", 4) ||
260 !strcmp (text, "who") ||
261 !strcmp (text, "uptime") ||
262 !strncmp (text, "tail ", 5)) {
263 static gboolean message_given = FALSE(0);
264 char *message;
265 const char *warning_format =
266 _("Warning: The command "gettext ("Warning: The command " "appears to be something actually useful.\n"
"Since this is a useless applet, you " "may not want to do this.\n"
"We strongly advise you against " "using %s for anything\n" "which would make the applet "
"\"practical\" or useful.")
267 "appears to be something actually useful.\n"gettext ("Warning: The command " "appears to be something actually useful.\n"
"Since this is a useless applet, you " "may not want to do this.\n"
"We strongly advise you against " "using %s for anything\n" "which would make the applet "
"\"practical\" or useful.")
268 "Since this is a useless applet, you "gettext ("Warning: The command " "appears to be something actually useful.\n"
"Since this is a useless applet, you " "may not want to do this.\n"
"We strongly advise you against " "using %s for anything\n" "which would make the applet "
"\"practical\" or useful.")
269 "may not want to do this.\n"gettext ("Warning: The command " "appears to be something actually useful.\n"
"Since this is a useless applet, you " "may not want to do this.\n"
"We strongly advise you against " "using %s for anything\n" "which would make the applet "
"\"practical\" or useful.")
270 "We strongly advise you against "gettext ("Warning: The command " "appears to be something actually useful.\n"
"Since this is a useless applet, you " "may not want to do this.\n"
"We strongly advise you against " "using %s for anything\n" "which would make the applet "
"\"practical\" or useful.")
271 "using %s for anything\n"gettext ("Warning: The command " "appears to be something actually useful.\n"
"Since this is a useless applet, you " "may not want to do this.\n"
"We strongly advise you against " "using %s for anything\n" "which would make the applet "
"\"practical\" or useful.")
272 "which would make the applet "gettext ("Warning: The command " "appears to be something actually useful.\n"
"Since this is a useless applet, you " "may not want to do this.\n"
"We strongly advise you against " "using %s for anything\n" "which would make the applet "
"\"practical\" or useful.")
273 "\"practical\" or useful.")gettext ("Warning: The command " "appears to be something actually useful.\n"
"Since this is a useless applet, you " "may not want to do this.\n"
"We strongly advise you against " "using %s for anything\n" "which would make the applet "
"\"practical\" or useful.")
;
274
275 if ( ! message_given) {
276 message = g_strdup_printf (warning_format, fish->name);
277
278 something_fishy_going_on (fish, message);
279
280 g_free (message);
281
282 message_given = TRUE(!(0));
283 }
284 }
285
286 g_settings_set_string (fish->settings, FISH_COMMAND_KEY"command", text);
287}
288
289static void n_frames_value_changed(CtkSpinButton* button, FishApplet* fish)
290{
291 g_settings_set_int (
292 fish->settings,
293 FISH_FRAMES_KEY"frames",
294 ctk_spin_button_get_value_as_int (button));
295}
296
297static void speed_value_changed (CtkSpinButton* button, FishApplet* fish)
298{
299 g_settings_set_double (
300 fish->settings,
301 FISH_SPEED_KEY"speed",
302 ctk_spin_button_get_value (button));
303}
304
305static void rotate_value_changed(CtkToggleButton* toggle, FishApplet* fish)
306{
307 g_settings_set_boolean (
308 fish->settings,
309 FISH_ROTATE_KEY"rotate",
310 ctk_toggle_button_get_active (toggle));
311}
312
313static gboolean delete_event(CtkWidget* widget, FishApplet* fish)
314{
315 ctk_widget_hide (widget);
316
317 return TRUE(!(0));
318}
319
320static void handle_response(CtkWidget* widget, int id, FishApplet* fish)
321{
322 if (id == CTK_RESPONSE_HELP) {
323 show_help (fish, "fish-settings");
324 return;
325 }
326
327 ctk_widget_hide (fish->preferences_dialog);
328}
329
330static void setup_sensitivity(FishApplet* fish, CtkBuilder* builder, const char* wid, const char* label, const char* label_post, const char* key)
331{
332 CtkWidget *w;
333
334 if (g_settings_is_writable (fish->settings, key)) {
335 return;
336 }
337
338 w = CTK_WIDGET (ctk_builder_get_object (builder, wid))((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((ctk_builder_get_object (builder, wid))), ((ctk_widget_get_type
()))))))
;
339 g_assert (w != NULL)do { if (w != ((void*)0)) ; else g_assertion_message_expr (((
gchar*) 0), "fish.c", 339, ((const char*) (__func__)), "w != NULL"
); } while (0)
;
340 ctk_widget_set_sensitive (w, FALSE(0));
341
342 if (label != NULL((void*)0)) {
343 w = CTK_WIDGET (ctk_builder_get_object (builder, label))((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((ctk_builder_get_object (builder, label))), ((ctk_widget_get_type
()))))))
;
344 g_assert (w != NULL)do { if (w != ((void*)0)) ; else g_assertion_message_expr (((
gchar*) 0), "fish.c", 344, ((const char*) (__func__)), "w != NULL"
); } while (0)
;
345 ctk_widget_set_sensitive (w, FALSE(0));
346 }
347 if (label_post != NULL((void*)0)) {
348 w = CTK_WIDGET (ctk_builder_get_object (builder, label_post))((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((ctk_builder_get_object (builder, label_post))), ((ctk_widget_get_type
()))))))
;
349 g_assert (w != NULL)do { if (w != ((void*)0)) ; else g_assertion_message_expr (((
gchar*) 0), "fish.c", 349, ((const char*) (__func__)), "w != NULL"
); } while (0)
;
350 ctk_widget_set_sensitive (w, FALSE(0));
351 }
352
353}
354
355static void chooser_preview_update(CtkFileChooser* file_chooser, gpointer data)
356{
357 CtkWidget *preview;
358 char *filename;
359 GdkPixbuf *pixbuf;
360 gboolean have_preview;
361
362 preview = CTK_WIDGET (data)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((data)), ((ctk_widget_get_type ()))))))
;
363 filename = ctk_file_chooser_get_preview_filename (file_chooser);
364
365 if (filename == NULL((void*)0))
366 return;
367
368 pixbuf = gdk_pixbuf_new_from_file_at_size (filename, 128, 128, NULL((void*)0));
369 have_preview = (pixbuf != NULL((void*)0));
370 g_free (filename);
371
372 ctk_image_set_from_pixbuf (CTK_IMAGE (preview)((((CtkImage*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((preview)), ((ctk_image_get_type ()))))))
, pixbuf);
373 if (pixbuf)
374 g_object_unref (pixbuf);
375
376 ctk_file_chooser_set_preview_widget_active (file_chooser,
377 have_preview);
378}
379
380static void display_preferences_dialog(CtkAction* action, FishApplet* fish)
381{
382 CtkBuilder *builder;
383 CtkWidget *button;
384 CtkFileFilter *filter;
385 CtkWidget *chooser_preview;
386 char *path;
387
388 if (fish->preferences_dialog) {
389 ctk_window_set_screen (CTK_WINDOW (fish->preferences_dialog)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((fish->preferences_dialog)), ((ctk_window_get_type ())
)))))
,
390 ctk_widget_get_screen (CTK_WIDGET (fish)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((fish)), ((ctk_widget_get_type ()))))))
));
391 ctk_window_present (CTK_WINDOW (fish->preferences_dialog)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((fish->preferences_dialog)), ((ctk_window_get_type ())
)))))
);
392 return;
393 }
394
395 builder = ctk_builder_new ();
396 ctk_builder_set_translation_domain (builder, GETTEXT_PACKAGE"cafe-panel");
397 ctk_builder_add_from_resource (builder, FISH_RESOURCE_PATH"/org/cafe/panel/applet/fish/" "fish.ui", NULL((void*)0));
398
399 fish->preferences_dialog = CTK_WIDGET (ctk_builder_get_object (builder, "fish_preferences_dialog"))((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((ctk_builder_get_object (builder, "fish_preferences_dialog"
))), ((ctk_widget_get_type ()))))))
;
400
401 g_object_add_weak_pointer (G_OBJECT (fish->preferences_dialog)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((fish->preferences_dialog)), (((GType) ((20) << (
2))))))))
,
402 (void**) &fish->preferences_dialog);
403
404 ctk_window_set_icon_name (CTK_WINDOW (fish->preferences_dialog)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((fish->preferences_dialog)), ((ctk_window_get_type ())
)))))
,
405 FISH_ICON"cafe-panel-fish");
406 ctk_dialog_set_default_response (
407 CTK_DIALOG (fish->preferences_dialog)((((CtkDialog*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((fish->preferences_dialog)), ((ctk_dialog_get_type ())
)))))
, CTK_RESPONSE_OK);
408
409 fish->name_entry = CTK_WIDGET (ctk_builder_get_object (builder, "name_entry"))((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((ctk_builder_get_object (builder, "name_entry"))), ((ctk_widget_get_type
()))))))
;
410 ctk_entry_set_text (CTK_ENTRY (fish->name_entry)((((CtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((fish->name_entry)), ((ctk_entry_get_type ()))))))
, fish->name);
411
412 g_signal_connect (fish->name_entry, "changed",g_signal_connect_data ((fish->name_entry), ("changed"), ((
(GCallback) (name_value_changed))), (fish), ((void*)0), (GConnectFlags
) 0)
413 G_CALLBACK (name_value_changed), fish)g_signal_connect_data ((fish->name_entry), ("changed"), ((
(GCallback) (name_value_changed))), (fish), ((void*)0), (GConnectFlags
) 0)
;
414
415 setup_sensitivity (fish, builder,
416 "name_entry" /* wid */,
417 "name_label" /* label */,
418 NULL((void*)0) /* label_post */,
419 FISH_NAME_KEY"name" /* key */);
420
421 fish->preview_image = CTK_WIDGET (ctk_builder_get_object (builder, "preview_image"))((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((ctk_builder_get_object (builder, "preview_image"))), ((ctk_widget_get_type
()))))))
;
422 if (fish->pixbuf)
423 ctk_image_set_from_pixbuf (CTK_IMAGE (fish->preview_image)((((CtkImage*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((fish->preview_image)), ((ctk_image_get_type ()))))))
,
424 fish->pixbuf);
425
426 fish->image_chooser = CTK_WIDGET (ctk_builder_get_object (builder, "image_chooser"))((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((ctk_builder_get_object (builder, "image_chooser"))), ((ctk_widget_get_type
()))))))
;
427 filter = ctk_file_filter_new ();
428 ctk_file_filter_set_name (filter, _("Images")gettext ("Images"));
429 ctk_file_filter_add_pixbuf_formats (filter);
430 ctk_file_chooser_add_filter (CTK_FILE_CHOOSER (fish->image_chooser)((((CtkFileChooser*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((fish->image_chooser)), ((ctk_file_chooser_get_type ()
))))))
,
431 filter);
432 ctk_file_chooser_set_filter (CTK_FILE_CHOOSER (fish->image_chooser)((((CtkFileChooser*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((fish->image_chooser)), ((ctk_file_chooser_get_type ()
))))))
,
433 filter);
434 chooser_preview = ctk_image_new ();
435 ctk_file_chooser_set_preview_widget (CTK_FILE_CHOOSER (fish->image_chooser)((((CtkFileChooser*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((fish->image_chooser)), ((ctk_file_chooser_get_type ()
))))))
,
436 chooser_preview);
437 g_signal_connect (fish->image_chooser, "update-preview",g_signal_connect_data ((fish->image_chooser), ("update-preview"
), (((GCallback) (chooser_preview_update))), (chooser_preview
), ((void*)0), (GConnectFlags) 0)
438 G_CALLBACK (chooser_preview_update), chooser_preview)g_signal_connect_data ((fish->image_chooser), ("update-preview"
), (((GCallback) (chooser_preview_update))), (chooser_preview
), ((void*)0), (GConnectFlags) 0)
;
439 path = get_image_path (fish);
440 ctk_file_chooser_set_filename (CTK_FILE_CHOOSER (fish->image_chooser)((((CtkFileChooser*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((fish->image_chooser)), ((ctk_file_chooser_get_type ()
))))))
,
441 path);
442 g_free (path);
443
444 g_signal_connect (fish->image_chooser, "selection-changed",g_signal_connect_data ((fish->image_chooser), ("selection-changed"
), (((GCallback) (image_value_changed))), (fish), ((void*)0),
(GConnectFlags) 0)
445 G_CALLBACK (image_value_changed), fish)g_signal_connect_data ((fish->image_chooser), ("selection-changed"
), (((GCallback) (image_value_changed))), (fish), ((void*)0),
(GConnectFlags) 0)
;
446
447 setup_sensitivity (fish, builder,
448 "image_chooser" /* wid */,
449 "image_label" /* label */,
450 NULL((void*)0) /* label_post */,
451 FISH_IMAGE_KEY"image" /* key */);
452
453 fish->command_label = CTK_WIDGET (ctk_builder_get_object (builder, "command_label"))((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((ctk_builder_get_object (builder, "command_label"))), ((ctk_widget_get_type
()))))))
;
454 fish->command_entry = CTK_WIDGET (ctk_builder_get_object (builder, "command_entry"))((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((ctk_builder_get_object (builder, "command_entry"))), ((ctk_widget_get_type
()))))))
;
455 ctk_entry_set_text (CTK_ENTRY (fish->command_entry)((((CtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((fish->command_entry)), ((ctk_entry_get_type ()))))))
, fish->command);
456
457 g_signal_connect (fish->command_entry, "changed",g_signal_connect_data ((fish->command_entry), ("changed"),
(((GCallback) (command_value_changed))), (fish), ((void*)0),
(GConnectFlags) 0)
458 G_CALLBACK (command_value_changed), fish)g_signal_connect_data ((fish->command_entry), ("changed"),
(((GCallback) (command_value_changed))), (fish), ((void*)0),
(GConnectFlags) 0)
;
459
460 setup_sensitivity (fish, builder,
461 "command_entry" /* wid */,
462 "command_label" /* label */,
463 NULL((void*)0) /* label_post */,
464 FISH_COMMAND_KEY"command" /* key */);
465
466 if (g_settings_get_boolean (fish->lockdown_settings, LOCKDOWN_DISABLE_COMMAND_LINE_KEY"disable-command-line")) {
467 ctk_widget_set_sensitive (fish->command_label, FALSE(0));
468 ctk_widget_set_sensitive (fish->command_entry, FALSE(0));
469 }
470
471 fish->frames_spin = CTK_WIDGET (ctk_builder_get_object (builder, "frames_spin"))((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((ctk_builder_get_object (builder, "frames_spin"))), ((ctk_widget_get_type
()))))))
;
472 ctk_spin_button_set_value (CTK_SPIN_BUTTON (fish->frames_spin)((((CtkSpinButton*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((fish->frames_spin)), ((ctk_spin_button_get_type ())))
)))
,
473 fish->n_frames);
474
475 g_signal_connect (fish->frames_spin, "value_changed",g_signal_connect_data ((fish->frames_spin), ("value_changed"
), (((GCallback) (n_frames_value_changed))), (fish), ((void*)
0), (GConnectFlags) 0)
476 G_CALLBACK (n_frames_value_changed), fish)g_signal_connect_data ((fish->frames_spin), ("value_changed"
), (((GCallback) (n_frames_value_changed))), (fish), ((void*)
0), (GConnectFlags) 0)
;
477
478 setup_sensitivity (fish, builder,
479 "frames_spin" /* wid */,
480 "frames_label" /* label */,
481 "frames_post_label" /* label_post */,
482 FISH_FRAMES_KEY"frames" /* key */);
483
484 fish->speed_spin = CTK_WIDGET (ctk_builder_get_object (builder, "speed_spin"))((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((ctk_builder_get_object (builder, "speed_spin"))), ((ctk_widget_get_type
()))))))
;
485 ctk_spin_button_set_value (CTK_SPIN_BUTTON (fish->speed_spin)((((CtkSpinButton*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((fish->speed_spin)), ((ctk_spin_button_get_type ()))))
))
, fish->speed);
486
487 g_signal_connect (fish->speed_spin, "value_changed",g_signal_connect_data ((fish->speed_spin), ("value_changed"
), (((GCallback) (speed_value_changed))), (fish), ((void*)0),
(GConnectFlags) 0)
488 G_CALLBACK (speed_value_changed), fish)g_signal_connect_data ((fish->speed_spin), ("value_changed"
), (((GCallback) (speed_value_changed))), (fish), ((void*)0),
(GConnectFlags) 0)
;
489
490 setup_sensitivity (fish, builder,
491 "speed_spin" /* wid */,
492 "speed_label" /* label */,
493 "speed_post_label" /* label_post */,
494 FISH_SPEED_KEY"speed" /* key */);
495
496 fish->rotate_toggle = CTK_WIDGET (ctk_builder_get_object (builder, "rotate_toggle"))((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((ctk_builder_get_object (builder, "rotate_toggle"))), ((ctk_widget_get_type
()))))))
;
497 ctk_toggle_button_set_active (
498 CTK_TOGGLE_BUTTON (fish->rotate_toggle)((((CtkToggleButton*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((fish->rotate_toggle)), ((ctk_toggle_button_get_type (
)))))))
, fish->rotate);
499
500 g_signal_connect (fish->rotate_toggle, "toggled",g_signal_connect_data ((fish->rotate_toggle), ("toggled"),
(((GCallback) (rotate_value_changed))), (fish), ((void*)0), (
GConnectFlags) 0)
501 G_CALLBACK (rotate_value_changed), fish)g_signal_connect_data ((fish->rotate_toggle), ("toggled"),
(((GCallback) (rotate_value_changed))), (fish), ((void*)0), (
GConnectFlags) 0)
;
502
503 setup_sensitivity (fish, builder,
504 "rotate_toggle" /* wid */,
505 NULL((void*)0) /* label */,
506 NULL((void*)0) /* label_post */,
507 FISH_ROTATE_KEY"rotate" /* key */);
508
509 g_signal_connect (fish->preferences_dialog, "delete_event",g_signal_connect_data ((fish->preferences_dialog), ("delete_event"
), (((GCallback) (delete_event))), (fish), ((void*)0), (GConnectFlags
) 0)
510 G_CALLBACK (delete_event), fish)g_signal_connect_data ((fish->preferences_dialog), ("delete_event"
), (((GCallback) (delete_event))), (fish), ((void*)0), (GConnectFlags
) 0)
;
511 g_signal_connect (fish->preferences_dialog, "response",g_signal_connect_data ((fish->preferences_dialog), ("response"
), (((GCallback) (handle_response))), (fish), ((void*)0), (GConnectFlags
) 0)
512 G_CALLBACK (handle_response), fish)g_signal_connect_data ((fish->preferences_dialog), ("response"
), (((GCallback) (handle_response))), (fish), ((void*)0), (GConnectFlags
) 0)
;
513
514 button = CTK_WIDGET (ctk_builder_get_object (builder, "done_button"))((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((ctk_builder_get_object (builder, "done_button"))), ((ctk_widget_get_type
()))))))
;
515 g_signal_connect_swapped (button, "clicked",g_signal_connect_data ((button), ("clicked"), ((GCallback) ctk_widget_hide
), (fish->preferences_dialog), ((void*)0), G_CONNECT_SWAPPED
)
516 (GCallback) ctk_widget_hide,g_signal_connect_data ((button), ("clicked"), ((GCallback) ctk_widget_hide
), (fish->preferences_dialog), ((void*)0), G_CONNECT_SWAPPED
)
517 fish->preferences_dialog)g_signal_connect_data ((button), ("clicked"), ((GCallback) ctk_widget_hide
), (fish->preferences_dialog), ((void*)0), G_CONNECT_SWAPPED
)
;
518
519 ctk_window_set_screen (CTK_WINDOW (fish->preferences_dialog)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((fish->preferences_dialog)), ((ctk_window_get_type ())
)))))
,
520 ctk_widget_get_screen (CTK_WIDGET (fish)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((fish)), ((ctk_widget_get_type ()))))))
));
521 ctk_window_set_resizable (CTK_WINDOW (fish->preferences_dialog)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((fish->preferences_dialog)), ((ctk_window_get_type ())
)))))
, FALSE(0));
522 ctk_window_present (CTK_WINDOW (fish->preferences_dialog)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((fish->preferences_dialog)), ((ctk_window_get_type ())
)))))
);
523
524 g_object_unref (builder);
525}
526
527static void display_help_dialog(CtkAction* action, FishApplet* fish)
528{
529 show_help(fish, NULL((void*)0));
530}
531
532static void display_about_dialog(CtkAction* action, FishApplet* fish)
533{
534 const char* author_format = _("%s the Fish")gettext ("%s the Fish");
535 const char* about_format = _("%s has no use what-so-ever. "gettext ("%s has no use what-so-ever. " "It only takes up disk space and "
"compilation time, and if loaded it also " "takes up precious panel space and "
"memory. Anybody found using it should be " "promptly sent for a psychiatric "
"evaluation.")
536 "It only takes up disk space and "gettext ("%s has no use what-so-ever. " "It only takes up disk space and "
"compilation time, and if loaded it also " "takes up precious panel space and "
"memory. Anybody found using it should be " "promptly sent for a psychiatric "
"evaluation.")
537 "compilation time, and if loaded it also "gettext ("%s has no use what-so-ever. " "It only takes up disk space and "
"compilation time, and if loaded it also " "takes up precious panel space and "
"memory. Anybody found using it should be " "promptly sent for a psychiatric "
"evaluation.")
538 "takes up precious panel space and "gettext ("%s has no use what-so-ever. " "It only takes up disk space and "
"compilation time, and if loaded it also " "takes up precious panel space and "
"memory. Anybody found using it should be " "promptly sent for a psychiatric "
"evaluation.")
539 "memory. Anybody found using it should be "gettext ("%s has no use what-so-ever. " "It only takes up disk space and "
"compilation time, and if loaded it also " "takes up precious panel space and "
"memory. Anybody found using it should be " "promptly sent for a psychiatric "
"evaluation.")
540 "promptly sent for a psychiatric "gettext ("%s has no use what-so-ever. " "It only takes up disk space and "
"compilation time, and if loaded it also " "takes up precious panel space and "
"memory. Anybody found using it should be " "promptly sent for a psychiatric "
"evaluation.")
541 "evaluation.")gettext ("%s has no use what-so-ever. " "It only takes up disk space and "
"compilation time, and if loaded it also " "takes up precious panel space and "
"memory. Anybody found using it should be " "promptly sent for a psychiatric "
"evaluation.")
;
542 const char* documenters [] = {
543 "Telsa Gwynne <hobbit@aloss.ukuu.org.uk>",
544 "Sun GNOME Documentation Team <gdocteam@sun.com>",
545 NULL((void*)0)
546 };
547
548 char* authors[3];
549 char* descr;
550
551 authors[0] = g_strdup_printf(author_format, fish->name);
552 authors[1] = _("(with minor help from George)")gettext ("(with minor help from George)");
553 authors[2] = NULL((void*)0);
554
555 descr = g_strdup_printf(about_format, fish->name);
556
557 ctk_show_about_dialog(NULL((void*)0),
558 "program-name", _("Fish")gettext ("Fish"),
559 "title", _("About Fish")gettext ("About Fish"),
560 "authors", authors,
561 "comments", descr,
562 "copyright", _("Copyright \xc2\xa9 1998-2002 Free Software Foundation, Inc.\n"gettext ("Copyright \xc2\xa9 1998-2002 Free Software Foundation, Inc.\n"
"Copyright \xc2\xa9 2002-2005 Vincent Untz\n" "Copyright \xc2\xa9 2012-2020 MATE developers\n"
"Copyright \xc2\xa9 2022-2024 Pablo Barciela")
563 "Copyright \xc2\xa9 2002-2005 Vincent Untz\n"gettext ("Copyright \xc2\xa9 1998-2002 Free Software Foundation, Inc.\n"
"Copyright \xc2\xa9 2002-2005 Vincent Untz\n" "Copyright \xc2\xa9 2012-2020 MATE developers\n"
"Copyright \xc2\xa9 2022-2024 Pablo Barciela")
564 "Copyright \xc2\xa9 2012-2020 MATE developers\n"gettext ("Copyright \xc2\xa9 1998-2002 Free Software Foundation, Inc.\n"
"Copyright \xc2\xa9 2002-2005 Vincent Untz\n" "Copyright \xc2\xa9 2012-2020 MATE developers\n"
"Copyright \xc2\xa9 2022-2024 Pablo Barciela")
565 "Copyright \xc2\xa9 2022-2024 Pablo Barciela")gettext ("Copyright \xc2\xa9 1998-2002 Free Software Foundation, Inc.\n"
"Copyright \xc2\xa9 2002-2005 Vincent Untz\n" "Copyright \xc2\xa9 2012-2020 MATE developers\n"
"Copyright \xc2\xa9 2022-2024 Pablo Barciela")
,
566 "documenters", documenters,
567 "logo-icon-name", FISH_ICON"cafe-panel-fish",
568 "translator-credits", _("translator-credits")gettext ("translator-credits"),
569 "version", VERSION"1.25.0", // "3.4.7.4ac19"
570 "website", "http://cafe-desktop.org/",
571 NULL((void*)0));
572
573 g_free(descr);
574 g_free(authors[0]);
575}
576
577static void set_ally_name_desc(CtkWidget* widget, FishApplet* fish)
578{
579 const char *name_format = _("%s the Fish")gettext ("%s the Fish");
580 const char *desc_format = _("%s the Fish, a contemporary oracle")gettext ("%s the Fish, a contemporary oracle");
581 AtkObject *obj;
582 char *desc, *name;
583
584 obj = ctk_widget_get_accessible (widget);
585 /* Return immediately if GAIL is not loaded */
586 if (!CTK_IS_ACCESSIBLE (obj)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(obj)); GType __t = ((ctk_accessible_get_type ())); gboolean __r
; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))
)
587 return;
588
589 name = g_strdup_printf (name_format, fish->name);
590 atk_object_set_name (obj, name);
591 g_free (name);
592
593 desc = g_strdup_printf (desc_format, fish->name);
594 atk_object_set_description (obj, desc);
595 g_free (desc);
596}
597
598static void something_fishy_going_on(FishApplet* fish, const char* message)
599{
600 CtkWidget *dialog;
601
602 dialog = ctk_message_dialog_new (NULL((void*)0),
603 CTK_DIALOG_DESTROY_WITH_PARENT,
604 CTK_MESSAGE_ERROR,
605 CTK_BUTTONS_CLOSE,
606 "%s", message);
607
608 g_signal_connect (dialog, "response",g_signal_connect_data ((dialog), ("response"), (((GCallback) (
ctk_widget_destroy))), (((void*)0)), ((void*)0), (GConnectFlags
) 0)
609 G_CALLBACK (ctk_widget_destroy),g_signal_connect_data ((dialog), ("response"), (((GCallback) (
ctk_widget_destroy))), (((void*)0)), ((void*)0), (GConnectFlags
) 0)
610 NULL)g_signal_connect_data ((dialog), ("response"), (((GCallback) (
ctk_widget_destroy))), (((void*)0)), ((void*)0), (GConnectFlags
) 0)
;
611
612 ctk_window_set_icon_name (CTK_WINDOW (dialog)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog)), ((ctk_window_get_type ()))))))
, FISH_ICON"cafe-panel-fish");
613 ctk_window_set_resizable (CTK_WINDOW (dialog)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog)), ((ctk_window_get_type ()))))))
, FALSE(0));
614 ctk_window_set_screen (CTK_WINDOW (dialog)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog)), ((ctk_window_get_type ()))))))
,
615 ctk_widget_get_screen (CTK_WIDGET (fish)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((fish)), ((ctk_widget_get_type ()))))))
));
616 ctk_widget_show (dialog);
617}
618
619static gboolean locate_fortune_command (FishApplet* fish, int* argcp, char*** argvp)
620{
621 char *prog = NULL((void*)0);
622
623 if (fish->command
624 && g_shell_parse_argv (fish->command, argcp, argvp, NULL((void*)0))) {
625 prog = g_find_program_in_path ((*argvp)[0]);
626 if (prog) {
627 g_free (prog);
628 return TRUE(!(0));
629 }
630
631 g_strfreev (*argvp);
632 }
633
634 prog = g_find_program_in_path ("fortune");
635 if (prog) {
636 g_free (prog);
637 if (g_shell_parse_argv ("fortune", argcp, argvp, NULL((void*)0)))
638 return FALSE(0);
639 }
640
641 if (g_file_test ("/usr/games/fortune", G_FILE_TEST_IS_EXECUTABLE)
642 && g_shell_parse_argv ("/usr/games/fortune", argcp, argvp, NULL((void*)0)))
643 return FALSE(0);
644
645 something_fishy_going_on (fish,
646 _("Unable to locate the command to execute")gettext ("Unable to locate the command to execute"));
647 *argvp = NULL((void*)0);
648 return FALSE(0);
649}
650
651#define FISH_RESPONSE_SPEAK1 1
652static inline void fish_close_channel(FishApplet* fish)
653{
654 if (fish->io_channel) {
655 g_io_channel_shutdown (fish->io_channel, TRUE(!(0)), NULL((void*)0));
656 g_io_channel_unref (fish->io_channel);
657 }
658 fish->io_channel = NULL((void*)0);
659}
660
661static void handle_fortune_response(CtkWidget* widget, int id, FishApplet* fish)
662{
663 if (id == FISH_RESPONSE_SPEAK1)
664 display_fortune_dialog (fish);
665 else {
666 /* if there is still a pipe, close it: if we hide the widget,
667 * the * output can't be seen */
668 if (fish->source_id)
669 g_source_remove (fish->source_id);
670 fish->source_id = 0;
671 fish_close_channel (fish);
672 ctk_widget_hide (fish->fortune_dialog);
673 }
674}
675
676static void update_fortune_dialog(FishApplet* fish)
677{
678 char *label_text;
679 char *text;
680
681 if (!fish->fortune_dialog || !fish->name)
682 return;
683
684 /* xgettext:no-c-format */
685 text = g_strdup_printf (_("%s the Fish")gettext ("%s the Fish"), fish->name);
686 ctk_window_set_title (CTK_WINDOW (fish->fortune_dialog)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((fish->fortune_dialog)), ((ctk_window_get_type ())))))
)
, text);
687 g_free (text);
688
689 /* xgettext:no-c-format */
690 label_text = g_strdup_printf (_("%s the Fish Says:")gettext ("%s the Fish Says:"), fish->name);
691
692 text = g_strdup_printf ("<big><big>%s</big></big>", label_text);
693 ctk_label_set_markup (CTK_LABEL (fish->fortune_label)((((CtkLabel*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((fish->fortune_label)), ((ctk_label_get_type ()))))))
, text);
694 g_free (text);
695
696 g_free (label_text);
697
698 set_ally_name_desc (fish->fortune_view, fish);
699}
700
701static void insert_fortune_text(FishApplet* fish, const char* text)
702{
703 CtkTextIter iter;
704
705 ctk_text_buffer_get_iter_at_offset (fish->fortune_buffer, &iter, -1);
706
707 ctk_text_buffer_insert_with_tags_by_name (fish->fortune_buffer, &iter,
708 text, -1, "monospace_tag",
709 NULL((void*)0));
710
711 while (ctk_events_pending ())
712 ctk_main_iteration ();
713}
714
715static void clear_fortune_text(FishApplet* fish)
716{
717 CtkTextIter begin, end;
718
719 ctk_text_buffer_get_iter_at_offset (fish->fortune_buffer, &begin, 0);
720 ctk_text_buffer_get_iter_at_offset (fish->fortune_buffer, &end, -1);
721
722 ctk_text_buffer_delete (fish->fortune_buffer, &begin, &end);
723 ctk_text_buffer_remove_tag_by_name (fish->fortune_buffer,
724 "monospace_tag", &begin, &end);
725
726 /* insert an empty line */
727 insert_fortune_text (fish, "\n");
728}
729
730static gboolean fish_read_output(GIOChannel* source, GIOCondition condition, gpointer data)
731{
732 char output[4096];
733 char *utf8_output;
734 gsize bytes_read;
735 GError *error = NULL((void*)0);
736 GIOStatus status;
737 FishApplet *fish;
738
739 fish = (FishApplet *) data;
740
741 if (!(condition & G_IO_IN)) {
742 fish->source_id = 0;
743 fish_close_channel (fish);
744 return FALSE(0);
745 }
746
747 status = g_io_channel_read_chars (source, output, 4096, &bytes_read,
748 &error);
749
750 if (error) {
751 char *message;
752
753 message = g_strdup_printf (_("Unable to read output from command\n\nDetails: %s")gettext ("Unable to read output from command\n\nDetails: %s"),
754 error->message);
755 something_fishy_going_on (fish, message);
756 g_free (message);
757 g_error_free (error);
758 fish->source_id = 0;
759 fish_close_channel (fish);
760 return FALSE(0);
761 }
762
763 if (status == G_IO_STATUS_AGAIN)
764 return TRUE(!(0));
765
766 if (bytes_read > 0) {
767 /* The output is not guarantied to be in UTF-8 format, most
768 * likely it's just in ASCII-7 or in the user locale
769 */
770 if (!g_utf8_validate (output, -1, NULL((void*)0)))
771 utf8_output = g_locale_to_utf8 (output, bytes_read,
772 NULL((void*)0), NULL((void*)0), NULL((void*)0));
773 else
774 utf8_output = g_strndup (output, bytes_read);
775
776 if (utf8_output)
777 insert_fortune_text (fish, utf8_output);
778
779 g_free (utf8_output);
780 }
781
782 if (status == G_IO_STATUS_EOF) {
783 fish->source_id = 0;
784 fish_close_channel (fish);
785 }
786 return (status != G_IO_STATUS_EOF);
787}
788
789/*
790 * Set the DISPLAY variable, to be use by g_spawn_async.
791 */
792static void
793set_environment (gpointer display)
794{
795 g_setenv ("DISPLAY", display, TRUE(!(0)));
796}
797
798static CtkWidget*
799panel_dialog_add_button (CtkDialog *dialog,
800 const gchar *button_text,
801 const gchar *icon_name,
802 gint response_id)
803{
804 CtkWidget *button;
805
806 button = ctk_button_new_with_mnemonic (button_text);
807 ctk_button_set_image (CTK_BUTTON (button)((((CtkButton*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((button)), ((ctk_button_get_type ()))))))
, ctk_image_new_from_icon_name (icon_name, CTK_ICON_SIZE_BUTTON));
808
809 ctk_button_set_use_underline (CTK_BUTTON (button)((((CtkButton*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((button)), ((ctk_button_get_type ()))))))
, TRUE(!(0)));
810 ctk_style_context_add_class (ctk_widget_get_style_context (button), "text-button");
811 ctk_widget_set_can_default (button, TRUE(!(0)));
812 ctk_widget_show (button);
813 ctk_dialog_add_action_widget (CTK_DIALOG (dialog)((((CtkDialog*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog)), ((ctk_dialog_get_type ()))))))
, button, response_id);
814
815 return button;
816}
817
818static void display_fortune_dialog(FishApplet* fish)
819{
820 GError *error = NULL((void*)0);
821 gboolean user_command;
822 int output;
823 const char *charset;
824 int argc;
825 char **argv;
826 CdkDisplay *display;
827 CdkScreen *screen;
828 char *display_name;
829
830 /* if there is still a pipe, close it */
831 if (fish->source_id)
832 g_source_remove (fish->source_id);
833 fish->source_id = 0;
834 fish_close_channel (fish);
835
836 user_command = locate_fortune_command (fish, &argc, &argv);
837 if (!argv)
838 return;
839
840 if (!fish->fortune_dialog) {
841 CtkWidget *scrolled;
842 CtkWidget *vbox;
843 CdkMonitor *monitor;
844 CdkRectangle monitor_geom;
845
846 fish->fortune_dialog = ctk_dialog_new ();
847 ctk_window_set_title (CTK_WINDOW (fish->fortune_dialog)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((fish->fortune_dialog)), ((ctk_window_get_type ())))))
)
, "");
848
849 ctk_dialog_add_button (CTK_DIALOG (fish->fortune_dialog)((((CtkDialog*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((fish->fortune_dialog)), ((ctk_dialog_get_type ())))))
)
,
850 _("_Speak again")gettext ("_Speak again"),
851 FISH_RESPONSE_SPEAK1);
852
853 panel_dialog_add_button (CTK_DIALOG (fish->fortune_dialog)((((CtkDialog*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((fish->fortune_dialog)), ((ctk_dialog_get_type ())))))
)
,
854 _("_Close")gettext ("_Close"), "window-close",
855 CTK_RESPONSE_CLOSE);
856
857 ctk_window_set_icon_name (CTK_WINDOW (fish->fortune_dialog)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((fish->fortune_dialog)), ((ctk_window_get_type ())))))
)
,
858 FISH_ICON"cafe-panel-fish");
859
860 ctk_dialog_set_default_response (
861 CTK_DIALOG (fish->fortune_dialog)((((CtkDialog*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((fish->fortune_dialog)), ((ctk_dialog_get_type ())))))
)
, CTK_RESPONSE_CLOSE);
862
863 g_signal_connect (fish->fortune_dialog, "delete_event",g_signal_connect_data ((fish->fortune_dialog), ("delete_event"
), (((GCallback) (delete_event))), (fish), ((void*)0), (GConnectFlags
) 0)
864 G_CALLBACK (delete_event), fish)g_signal_connect_data ((fish->fortune_dialog), ("delete_event"
), (((GCallback) (delete_event))), (fish), ((void*)0), (GConnectFlags
) 0)
;
865 g_signal_connect (fish->fortune_dialog, "response",g_signal_connect_data ((fish->fortune_dialog), ("response"
), (((GCallback) (handle_fortune_response))), (fish), ((void*
)0), (GConnectFlags) 0)
866 G_CALLBACK (handle_fortune_response), fish)g_signal_connect_data ((fish->fortune_dialog), ("response"
), (((GCallback) (handle_fortune_response))), (fish), ((void*
)0), (GConnectFlags) 0)
;
867
868 monitor = cdk_display_get_monitor_at_window (ctk_widget_get_display (CTK_WIDGET (fish)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((fish)), ((ctk_widget_get_type ()))))))
),
869 ctk_widget_get_window (CTK_WIDGET (fish)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((fish)), ((ctk_widget_get_type ()))))))
));
870 cdk_monitor_get_geometry(monitor, &monitor_geom);
871 ctk_window_set_default_size (CTK_WINDOW (fish->fortune_dialog)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((fish->fortune_dialog)), ((ctk_window_get_type ())))))
)
,
872 MIN (600, monitor_geom.width * 0.9)(((600) < (monitor_geom.width * 0.9)) ? (600) : (monitor_geom
.width * 0.9))
,
873 MIN (350, monitor_geom.height * 0.9)(((350) < (monitor_geom.height * 0.9)) ? (350) : (monitor_geom
.height * 0.9))
);
874
875 fish->fortune_view = ctk_text_view_new ();
876 ctk_text_view_set_editable (CTK_TEXT_VIEW (fish->fortune_view)((((CtkTextView*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((fish->fortune_view)), ((ctk_text_view_get_type ()))))
))
, FALSE(0));
877 ctk_text_view_set_cursor_visible (CTK_TEXT_VIEW (fish->fortune_view)((((CtkTextView*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((fish->fortune_view)), ((ctk_text_view_get_type ()))))
))
, FALSE(0));
878 ctk_text_view_set_left_margin (CTK_TEXT_VIEW (fish->fortune_view)((((CtkTextView*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((fish->fortune_view)), ((ctk_text_view_get_type ()))))
))
, 10);
879 ctk_text_view_set_right_margin (CTK_TEXT_VIEW (fish->fortune_view)((((CtkTextView*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((fish->fortune_view)), ((ctk_text_view_get_type ()))))
))
, 10);
880 fish->fortune_buffer =
881 ctk_text_view_get_buffer (CTK_TEXT_VIEW (fish->fortune_view)((((CtkTextView*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((fish->fortune_view)), ((ctk_text_view_get_type ()))))
))
);
882
883 ctk_text_buffer_create_tag (CTK_TEXT_BUFFER (fish->fortune_buffer)((((CtkTextBuffer*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((fish->fortune_buffer)), ((ctk_text_buffer_get_type ()
))))))
,
884 "monospace_tag", "family",
885 "Monospace", NULL((void*)0));
886
887 scrolled = ctk_scrolled_window_new (NULL((void*)0), NULL((void*)0));
888 ctk_scrolled_window_set_policy (CTK_SCROLLED_WINDOW (scrolled)((((CtkScrolledWindow*) (void *) g_type_check_instance_cast (
(GTypeInstance*) ((scrolled)), ((ctk_scrolled_window_get_type
()))))))
,
889 CTK_POLICY_AUTOMATIC,
890 CTK_POLICY_AUTOMATIC);
891 ctk_scrolled_window_set_shadow_type (CTK_SCROLLED_WINDOW (scrolled)((((CtkScrolledWindow*) (void *) g_type_check_instance_cast (
(GTypeInstance*) ((scrolled)), ((ctk_scrolled_window_get_type
()))))))
,
892 CTK_SHADOW_IN);
893
894 ctk_container_add (CTK_CONTAINER (scrolled)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((scrolled)), ((ctk_container_get_type ()))))))
, fish->fortune_view);
895
896 fish->fortune_label = ctk_label_new ("");
897 ctk_label_set_ellipsize (CTK_LABEL (fish->fortune_label)((((CtkLabel*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((fish->fortune_label)), ((ctk_label_get_type ()))))))
,
898 PANGO_ELLIPSIZE_MIDDLE);
899 fish->fortune_cmd_label = ctk_label_new ("");
900 ctk_label_set_xalign (CTK_LABEL (fish->fortune_cmd_label)((((CtkLabel*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((fish->fortune_cmd_label)), ((ctk_label_get_type ())))
)))
, 0.0);
901 ctk_label_set_yalign (CTK_LABEL (fish->fortune_cmd_label)((((CtkLabel*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((fish->fortune_cmd_label)), ((ctk_label_get_type ())))
)))
, 0.5);
902
903 vbox = ctk_dialog_get_content_area (CTK_DIALOG (fish->fortune_dialog)((((CtkDialog*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((fish->fortune_dialog)), ((ctk_dialog_get_type ())))))
)
);
904 ctk_box_pack_start (CTK_BOX (vbox)((((CtkBox*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((vbox)), ((ctk_box_get_type ()))))))
,
905 fish->fortune_label,
906 FALSE(0), FALSE(0), 6);
907
908 ctk_box_pack_start (CTK_BOX (vbox)((((CtkBox*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((vbox)), ((ctk_box_get_type ()))))))
,
909 scrolled,
910 TRUE(!(0)), TRUE(!(0)), 6);
911
912 ctk_box_pack_start (CTK_BOX (vbox)((((CtkBox*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((vbox)), ((ctk_box_get_type ()))))))
,
913 fish->fortune_cmd_label,
914 FALSE(0), FALSE(0), 6);
915
916 update_fortune_dialog (fish);
917
918 /* We don't show_all for the dialog since fortune_cmd_label
919 * might need to be hidden
920 * The dialog will be shown with ctk_window_present later */
921 ctk_widget_show (scrolled);
922 ctk_widget_show (fish->fortune_view);
923 ctk_widget_show (fish->fortune_label);
924 }
925
926 if (!user_command) {
927 char *command;
928 char * text;
929
930 command = g_markup_printf_escaped ("<tt>%s</tt>", argv[0]);
931 text = g_strdup_printf (_("The configured command is not "gettext ("The configured command is not " "working and has been replaced by: "
"%s")
932 "working and has been replaced by: "gettext ("The configured command is not " "working and has been replaced by: "
"%s")
933 "%s")gettext ("The configured command is not " "working and has been replaced by: "
"%s")
, command);
934 ctk_label_set_markup (CTK_LABEL (fish->fortune_cmd_label)((((CtkLabel*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((fish->fortune_cmd_label)), ((ctk_label_get_type ())))
)))
,
935 text);
936 g_free (command);
937 g_free (text);
938 ctk_widget_show (fish->fortune_cmd_label);
939 } else {
940 ctk_widget_hide (fish->fortune_cmd_label);
941 }
942
943 clear_fortune_text (fish);
944
945 screen = ctk_widget_get_screen (CTK_WIDGET (fish)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((fish)), ((ctk_widget_get_type ()))))))
);
946 display = cdk_screen_get_display (screen);
947 display_name = g_strdup (cdk_display_get_name (display))g_strdup_inline (cdk_display_get_name (display));
948 g_spawn_async_with_pipes (NULL((void*)0), /* working directory */
949 argv,
950 NULL((void*)0), /* envp */
951 G_SPAWN_SEARCH_PATH|G_SPAWN_STDERR_TO_DEV_NULL,
952 set_environment,
953 &display_name,
954 NULL((void*)0), /* child pid */
955 NULL((void*)0), /* stdin */
956 &output,
957 NULL((void*)0), /* stderr */
958 &error);
959 g_free (display_name);
960
961 if (error) {
962 char *message;
963
964 message = g_strdup_printf (_("Unable to execute '%s'\n\nDetails: %s")gettext ("Unable to execute '%s'\n\nDetails: %s"),
965 argv[0], error->message);
966 something_fishy_going_on (fish, message);
967 g_free (message);
968 g_error_free (error);
969 g_strfreev (argv);
970 return;
971 }
972
973 fish->io_channel = g_io_channel_unix_new (output);
974 /* set the correct encoding if the locale is not using UTF-8 */
975 if (!g_get_charset (&charset))
976 g_io_channel_set_encoding(fish->io_channel, charset, &error);
977 if (error) {
978 char *message;
979
980 message = g_strdup_printf (_("Unable to read from '%s'\n\nDetails: %s")gettext ("Unable to read from '%s'\n\nDetails: %s"),
981 argv[0], error->message);
982 something_fishy_going_on (fish, message);
983 g_free (message);
984 g_error_free (error);
985 g_strfreev (argv);
986 return;
987 }
988
989 g_strfreev (argv);
990
991 fish->source_id = g_io_add_watch (fish->io_channel,
992 G_IO_IN|G_IO_ERR|G_IO_HUP|G_IO_NVAL,
993 fish_read_output, fish);
994
995 ctk_window_set_screen (CTK_WINDOW (fish->fortune_dialog)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((fish->fortune_dialog)), ((ctk_window_get_type ())))))
)
,
996 ctk_widget_get_screen (CTK_WIDGET (fish)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((fish)), ((ctk_widget_get_type ()))))))
));
997 ctk_window_present (CTK_WINDOW (fish->fortune_dialog)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((fish->fortune_dialog)), ((ctk_window_get_type ())))))
)
);
998}
999
1000static void name_changed_notify(GSettings* settings, gchar* key, FishApplet* fish)
1001{
1002 char *value;
1003
1004 value = g_settings_get_string (settings, key);
1005
1006 if (!value [0] || (fish->name && !strcmp (fish->name, value)))
1007 return;
1008
1009 if (fish->name)
1010 g_free (fish->name);
1011 fish->name = g_strdup (value)g_strdup_inline (value);
1012
1013 update_fortune_dialog (fish);
1014 set_tooltip (fish);
1015 set_ally_name_desc (CTK_WIDGET (fish)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((fish)), ((ctk_widget_get_type ()))))))
, fish);
1016
1017 if (fish->name_entry &&
1018 strcmp (ctk_entry_get_text (CTK_ENTRY (fish->name_entry)((((CtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((fish->name_entry)), ((ctk_entry_get_type ()))))))
), fish->name))
1019 ctk_entry_set_text (CTK_ENTRY (fish->name_entry)((((CtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((fish->name_entry)), ((ctk_entry_get_type ()))))))
, fish->name);
1020
1021 if (value)
1022 g_free (value);
1023}
1024
1025static void image_changed_notify(GSettings* settings, gchar* key, FishApplet* fish)
1026{
1027 char *value;
1028
1029 value = g_settings_get_string (settings, key);
1030
1031 if (!value [0] || (fish->image && !strcmp (fish->image, value)))
1032 return;
1033
1034 if (fish->image)
1035 g_free (fish->image);
1036 fish->image = g_strdup (value)g_strdup_inline (value);
1037
1038 load_fish_image (fish);
1039 update_pixmap (fish);
1040
1041 if (fish->image_chooser) {
1042 char *path_gsettings;
1043 char *path_chooser;
1044
1045 path_gsettings = get_image_path (fish);
1046 path_chooser = ctk_file_chooser_get_filename (CTK_FILE_CHOOSER (fish->image_chooser)((((CtkFileChooser*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((fish->image_chooser)), ((ctk_file_chooser_get_type ()
))))))
);
1047 if (strcmp (path_gsettings, path_chooser))
1048 ctk_file_chooser_set_filename (CTK_FILE_CHOOSER (fish->image_chooser)((((CtkFileChooser*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((fish->image_chooser)), ((ctk_file_chooser_get_type ()
))))))
,
1049 path_gsettings);
1050
1051 g_free (path_gsettings);
1052 g_free (path_chooser);
1053 }
1054
1055 if (value)
1056 g_free (value);
1057}
1058
1059static void command_changed_notify(GSettings* settings, gchar* key, FishApplet* fish)
1060{
1061 char *value;
1062
1063 value = g_settings_get_string (settings, key);
1064
1065 if (fish->command && !strcmp (fish->command, value))
1066 return;
1067
1068 if (fish->command)
1069 g_free (fish->command);
1070 fish->command = g_strdup (value)g_strdup_inline (value);
1071
1072 if (fish->command_entry &&
1073 strcmp (ctk_entry_get_text (CTK_ENTRY (fish->command_entry)((((CtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((fish->command_entry)), ((ctk_entry_get_type ()))))))
), fish->command))
1074 ctk_entry_set_text (CTK_ENTRY (fish->command_entry)((((CtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((fish->command_entry)), ((ctk_entry_get_type ()))))))
, fish->command);
1075
1076 if (value)
1077 g_free (value);
1078}
1079
1080static void n_frames_changed_notify(GSettings* settings, gchar* key, FishApplet* fish)
1081{
1082 int value;
1083
1084 value = g_settings_get_int (settings, key);
1085
1086 if (fish->n_frames == value)
1087 return;
1088
1089 fish->n_frames = value;
1090
1091 if (fish->n_frames <= 0)
1092 fish->n_frames = 1;
1093
1094 update_pixmap (fish);
1095
1096 if (fish->frames_spin &&
1097 ctk_spin_button_get_value_as_int (CTK_SPIN_BUTTON (fish->frames_spin)((((CtkSpinButton*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((fish->frames_spin)), ((ctk_spin_button_get_type ())))
)))
) != fish->n_frames)
1098 ctk_spin_button_set_value (CTK_SPIN_BUTTON (fish->frames_spin)((((CtkSpinButton*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((fish->frames_spin)), ((ctk_spin_button_get_type ())))
)))
, fish->n_frames);
1099}
1100
1101static char* get_location(void)
1102{
1103 static char location [256];
1104 char *buffer;
1105 FILE *zone;
1106 int i, len, count;
1107
1108 /* Old method : works for glibc < 2.2 */
1109 zone = fopen("/etc/timezone", "r");
1110 if (zone) {
1111 count = fscanf (zone, "%255s", location);
1112 fclose (zone);
1113 /* if we could read it, we return what we got */
1114 if (count == 1)
1115 return location;
1116 }
1117
1118 /* New method : works for glibc 2.2 */
1119 /* FIXME: this is broken for many distros, see the clock code */
1120 buffer = g_file_read_link ("/etc/localtime", NULL((void*)0));
1121 if (!buffer)
1122 return NULL((void*)0);
1123
1124 len = strlen (buffer);
1125 for (i = len, count = 0; (i > 0) && (count != 2); i--)
1126 if (buffer [i] == '/')
1127 count++;
1128
1129 if (count != 2) {
1130 g_free (buffer);
1131 return NULL((void*)0);
1132 }
1133
1134 memcpy (location, &buffer [i + 2], len - i - 2);
1135 g_free (buffer);
1136
1137 return location;
1138}
1139
1140static void init_fools_day(void)
1141{
1142 const char *spanish_timezones [] = {
1143 "Europe/Madrid",
1144 "Africa/Ceuta",
1145 "Atlantic/Canary",
1146 "America/Mexico_City",
1147 "Mexico/BajaSur",
1148 "Mexico/BajaNorte",
1149 "Mexico/General",
1150 NULL((void*)0)
1151 };
1152 char *location;
1153 int i;
1154
1155 if (!(location = get_location ()))
1156 return;
1157
1158 fools_day = 1; /* 1st */
1159 fools_month = 3; /* April */
1160 fools_hour_start = 0; /* Midnight */
1161 fools_hour_end = 12; /* Apparently jokes should stop at midday */
1162
1163 for (i = 0; spanish_timezones [i]; i++)
1164 if (!g_ascii_strcasecmp (spanish_timezones [i], location)) {
1165 /* Hah!, We are in Spain or Mexico
1166 * Spanish fool's day is 28th December
1167 */
1168 fools_day = 28;
1169 fools_month = 11;
1170 return;
1171 }
1172}
1173
1174static void check_april_fools(FishApplet* fish)
1175{
1176 struct tm *tm;
1177 time_t now;
1178
1179 time (&now);
1180 tm = localtime (&now);
1181
1182 if (fish->april_fools &&
1183 (tm->tm_mon != fools_month ||
1184 tm->tm_mday != fools_day ||
1185 tm->tm_hour >= fools_hour_end)) {
1186 fish->april_fools = FALSE(0);
1187 update_pixmap (fish);
1188 } else if (tm->tm_mon == fools_month &&
1189 tm->tm_mday == fools_day &&
1190 tm->tm_hour >= fools_hour_start &&
1191 tm->tm_hour <= fools_hour_end) {
1192 fish->april_fools = TRUE(!(0));
1193 update_pixmap (fish);
1194 }
1195}
1196
1197static gboolean timeout_handler(gpointer data)
1198{
1199 FishApplet *fish = (FishApplet *) data;
1200
1201 check_april_fools (fish);
1202
1203 if (fish->april_fools)
1204 return TRUE(!(0));
1205
1206 fish->current_frame++;
1207 if (fish->current_frame >= fish->n_frames)
1208 fish->current_frame = 0;
1209
1210 ctk_widget_queue_draw (fish->drawing_area);
1211
1212 return TRUE(!(0));
1213}
1214
1215static void setup_timeout(FishApplet *fish)
1216{
1217 if (fish->timeout)
1218 g_source_remove (fish->timeout);
1219
1220 fish->timeout = g_timeout_add (fish->speed * 1000,
1221 timeout_handler,
1222 fish);
1223}
1224
1225static void speed_changed_notify(GSettings* settings, gchar* key, FishApplet* fish)
1226{
1227 gdouble value;
1228
1229 value = g_settings_get_double (settings, key);
1230
1231 if (fish->speed == value)
1232 return;
1233 fish->speed = value;
1234
1235 setup_timeout (fish);
1236
1237 if (fish->speed_spin &&
1238 ctk_spin_button_get_value (CTK_SPIN_BUTTON (fish->frames_spin)((((CtkSpinButton*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((fish->frames_spin)), ((ctk_spin_button_get_type ())))
)))
) != fish->speed)
1239 ctk_spin_button_set_value (CTK_SPIN_BUTTON (fish->speed_spin)((((CtkSpinButton*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((fish->speed_spin)), ((ctk_spin_button_get_type ()))))
))
, fish->speed);
1240}
1241
1242static void rotate_changed_notify(GSettings* settings, gchar* key, FishApplet* fish)
1243{
1244 gboolean value;
1245
1246 value = g_settings_get_boolean (settings, key);
1247
1248 if (fish->rotate == value)
1249 return;
1250 fish->rotate = value;
1251
1252 if (fish->orientation == CAFE_PANEL_APPLET_ORIENT_LEFT ||
1253 fish->orientation == CAFE_PANEL_APPLET_ORIENT_RIGHT)
1254 update_pixmap (fish);
1255
1256 if (fish->rotate_toggle &&
1257 ctk_toggle_button_get_active (CTK_TOGGLE_BUTTON (fish->rotate_toggle)((((CtkToggleButton*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((fish->rotate_toggle)), ((ctk_toggle_button_get_type (
)))))))
) != fish->rotate)
1258 ctk_toggle_button_set_active (
1259 CTK_TOGGLE_BUTTON (fish->rotate_toggle)((((CtkToggleButton*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((fish->rotate_toggle)), ((ctk_toggle_button_get_type (
)))))))
, fish->rotate);
1260}
1261
1262static void fish_disable_commande_line_notify(GSettings* settings, gchar* key, FishApplet* fish)
1263{
1264 gboolean locked_down;
1265
1266 locked_down = !g_settings_get_boolean (settings, key);
1267
1268 if (fish->command_label != NULL((void*)0))
1269 ctk_widget_set_sensitive (fish->command_label, locked_down);
1270 if (fish->command_entry != NULL((void*)0))
1271 ctk_widget_set_sensitive (fish->command_entry, locked_down);
1272}
1273
1274static void setup_gsettings(FishApplet* fish)
1275{
1276 CafePanelApplet *applet = (CafePanelApplet *) fish;
1277
1278 fish->settings = cafe_panel_applet_settings_new (applet, FISH_SCHEMA"org.cafe.panel.applet.fish");
1279 fish->lockdown_settings = g_settings_new (LOCKDOWN_SCHEMA"org.cafe.lockdown");
1280
1281 g_signal_connect (fish->settings,g_signal_connect_data ((fish->settings), ("changed::" "name"
), (((GCallback) (name_changed_notify))), (fish), ((void*)0),
(GConnectFlags) 0)
1282 "changed::" FISH_NAME_KEY,g_signal_connect_data ((fish->settings), ("changed::" "name"
), (((GCallback) (name_changed_notify))), (fish), ((void*)0),
(GConnectFlags) 0)
1283 G_CALLBACK (name_changed_notify),g_signal_connect_data ((fish->settings), ("changed::" "name"
), (((GCallback) (name_changed_notify))), (fish), ((void*)0),
(GConnectFlags) 0)
1284 fish)g_signal_connect_data ((fish->settings), ("changed::" "name"
), (((GCallback) (name_changed_notify))), (fish), ((void*)0),
(GConnectFlags) 0)
;
1285 g_signal_connect (fish->settings,g_signal_connect_data ((fish->settings), ("changed::" "image"
), (((GCallback) (image_changed_notify))), (fish), ((void*)0)
, (GConnectFlags) 0)
1286 "changed::" FISH_IMAGE_KEY,g_signal_connect_data ((fish->settings), ("changed::" "image"
), (((GCallback) (image_changed_notify))), (fish), ((void*)0)
, (GConnectFlags) 0)
1287 G_CALLBACK (image_changed_notify),g_signal_connect_data ((fish->settings), ("changed::" "image"
), (((GCallback) (image_changed_notify))), (fish), ((void*)0)
, (GConnectFlags) 0)
1288 fish)g_signal_connect_data ((fish->settings), ("changed::" "image"
), (((GCallback) (image_changed_notify))), (fish), ((void*)0)
, (GConnectFlags) 0)
;
1289 g_signal_connect (fish->settings,g_signal_connect_data ((fish->settings), ("changed::" "command"
), (((GCallback) (command_changed_notify))), (fish), ((void*)
0), (GConnectFlags) 0)
1290 "changed::" FISH_COMMAND_KEY,g_signal_connect_data ((fish->settings), ("changed::" "command"
), (((GCallback) (command_changed_notify))), (fish), ((void*)
0), (GConnectFlags) 0)
1291 G_CALLBACK (command_changed_notify),g_signal_connect_data ((fish->settings), ("changed::" "command"
), (((GCallback) (command_changed_notify))), (fish), ((void*)
0), (GConnectFlags) 0)
1292 fish)g_signal_connect_data ((fish->settings), ("changed::" "command"
), (((GCallback) (command_changed_notify))), (fish), ((void*)
0), (GConnectFlags) 0)
;
1293 g_signal_connect (fish->settings,g_signal_connect_data ((fish->settings), ("changed::" "frames"
), (((GCallback) (n_frames_changed_notify))), (fish), ((void*
)0), (GConnectFlags) 0)
1294 "changed::" FISH_FRAMES_KEY,g_signal_connect_data ((fish->settings), ("changed::" "frames"
), (((GCallback) (n_frames_changed_notify))), (fish), ((void*
)0), (GConnectFlags) 0)
1295 G_CALLBACK (n_frames_changed_notify),g_signal_connect_data ((fish->settings), ("changed::" "frames"
), (((GCallback) (n_frames_changed_notify))), (fish), ((void*
)0), (GConnectFlags) 0)
1296 fish)g_signal_connect_data ((fish->settings), ("changed::" "frames"
), (((GCallback) (n_frames_changed_notify))), (fish), ((void*
)0), (GConnectFlags) 0)
;
1297 g_signal_connect (fish->settings,g_signal_connect_data ((fish->settings), ("changed::" "speed"
), (((GCallback) (speed_changed_notify))), (fish), ((void*)0)
, (GConnectFlags) 0)
1298 "changed::" FISH_SPEED_KEY,g_signal_connect_data ((fish->settings), ("changed::" "speed"
), (((GCallback) (speed_changed_notify))), (fish), ((void*)0)
, (GConnectFlags) 0)
1299 G_CALLBACK (speed_changed_notify),g_signal_connect_data ((fish->settings), ("changed::" "speed"
), (((GCallback) (speed_changed_notify))), (fish), ((void*)0)
, (GConnectFlags) 0)
1300 fish)g_signal_connect_data ((fish->settings), ("changed::" "speed"
), (((GCallback) (speed_changed_notify))), (fish), ((void*)0)
, (GConnectFlags) 0)
;
1301 g_signal_connect (fish->settings,g_signal_connect_data ((fish->settings), ("changed::" "rotate"
), (((GCallback) (rotate_changed_notify))), (fish), ((void*)0
), (GConnectFlags) 0)
1302 "changed::" FISH_ROTATE_KEY,g_signal_connect_data ((fish->settings), ("changed::" "rotate"
), (((GCallback) (rotate_changed_notify))), (fish), ((void*)0
), (GConnectFlags) 0)
1303 G_CALLBACK (rotate_changed_notify),g_signal_connect_data ((fish->settings), ("changed::" "rotate"
), (((GCallback) (rotate_changed_notify))), (fish), ((void*)0
), (GConnectFlags) 0)
1304 fish)g_signal_connect_data ((fish->settings), ("changed::" "rotate"
), (((GCallback) (rotate_changed_notify))), (fish), ((void*)0
), (GConnectFlags) 0)
;
1305 g_signal_connect (fish->lockdown_settings,g_signal_connect_data ((fish->lockdown_settings), ("changed::"
"disable-command-line"), (((GCallback) (fish_disable_commande_line_notify
))), (fish), ((void*)0), (GConnectFlags) 0)
1306 "changed::" LOCKDOWN_DISABLE_COMMAND_LINE_KEY,g_signal_connect_data ((fish->lockdown_settings), ("changed::"
"disable-command-line"), (((GCallback) (fish_disable_commande_line_notify
))), (fish), ((void*)0), (GConnectFlags) 0)
1307 G_CALLBACK (fish_disable_commande_line_notify),g_signal_connect_data ((fish->lockdown_settings), ("changed::"
"disable-command-line"), (((GCallback) (fish_disable_commande_line_notify
))), (fish), ((void*)0), (GConnectFlags) 0)
1308 fish)g_signal_connect_data ((fish->lockdown_settings), ("changed::"
"disable-command-line"), (((GCallback) (fish_disable_commande_line_notify
))), (fish), ((void*)0), (GConnectFlags) 0)
;
1309}
1310
1311static gboolean load_fish_image(FishApplet* fish)
1312{
1313 GdkPixbuf *pixbuf;
1314 GError *error = NULL((void*)0);
1315 char *path = NULL((void*)0);
1316
1317 if (!fish->image)
1318 return FALSE(0);
1319
1320 path = get_image_path (fish);
1321
1322 pixbuf = gdk_pixbuf_new_from_file (path, &error);
1323 if (error) {
1324 g_warning ("Cannot load '%s': %s", path, error->message);
1325 g_error_free (error);
1326 g_free (path);
1327 return FALSE(0);
1328 }
1329
1330 if (fish->pixbuf)
1331 g_object_unref (fish->pixbuf);
1332 fish->pixbuf = pixbuf;
1333
1334 if (fish->preview_image)
1335 ctk_image_set_from_pixbuf (CTK_IMAGE (fish->preview_image)((((CtkImage*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((fish->preview_image)), ((ctk_image_get_type ()))))))
,
1336 fish->pixbuf);
1337
1338 g_free (path);
1339
1340 return TRUE(!(0));
1341}
1342
1343static gboolean
1344update_pixmap_in_idle (gpointer data)
1345{
1346 update_pixmap (FISH_APPLET (data)((((FishApplet*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((data)), (fish_applet_get_type())))))
);
1347 return FALSE(0);
1348}
1349
1350static void update_pixmap(FishApplet* fish)
1351{
1352 CtkWidget *widget = fish->drawing_area;
1353 CtkRequisition prev_requisition;
1354 CtkAllocation allocation;
1355 int width = -1;
1356 int height = -1;
1357 int pixbuf_width = -1;
1358 int pixbuf_height = -1;
1359 gboolean rotate = FALSE(0);
1360 cairo_t *cr;
1361 cairo_matrix_t matrix;
1362 cairo_pattern_t *pattern;
1363
1364 ctk_widget_get_allocation (widget, &allocation);
1365
1366 if (!ctk_widget_get_realized (widget) ||
1367 allocation.width <= 0 ||
1368 allocation.height <= 0)
1369 return;
1370
1371 if (!fish->pixbuf && !load_fish_image (fish))
1372 return;
1373
1374 if (fish->rotate &&
1375 (fish->orientation == CAFE_PANEL_APPLET_ORIENT_LEFT ||
1376 fish->orientation == CAFE_PANEL_APPLET_ORIENT_RIGHT))
1377 rotate = TRUE(!(0));
1378
1379 pixbuf_width = gdk_pixbuf_get_width (fish->pixbuf);
1380 pixbuf_height = gdk_pixbuf_get_height (fish->pixbuf);
1381
1382 prev_requisition = fish->requisition;
1383
1384 if (fish->orientation == CAFE_PANEL_APPLET_ORIENT_UP ||
1385 fish->orientation == CAFE_PANEL_APPLET_ORIENT_DOWN) {
1386 height = allocation.height;
1387 width = pixbuf_width * ((gdouble) height / pixbuf_height);
1388 fish->requisition.width = width / fish->n_frames;
1389 fish->requisition.height = height;
1390 } else {
1391 if (!rotate) {
1392 width = allocation.width * fish->n_frames;
1393 height = pixbuf_height * ((gdouble) width / pixbuf_width);
1394 fish->requisition.width = allocation.width;
1395 fish->requisition.height = height;
1396 } else {
1397 width = allocation.width;
1398 height = pixbuf_width * ((gdouble) width / pixbuf_height);
1399 fish->requisition.width = width;
1400 fish->requisition.height = height / fish->n_frames;
1401 }
1402 }
1403
1404 if (prev_requisition.width != fish->requisition.width ||
1405 prev_requisition.height != fish->requisition.height) {
1406 ctk_widget_set_size_request (widget,
1407 fish->requisition.width,
1408 fish->requisition.height);
1409 }
1410
1411 g_assert (width != -1 && height != -1)do { if (width != -1 && height != -1) ; else g_assertion_message_expr
(((gchar*) 0), "fish.c", 1411, ((const char*) (__func__)), "width != -1 && height != -1"
); } while (0)
;
1412
1413 if (width == 0 || height == 0)
1414 return;
1415
1416 if (fish->surface)
1417 cairo_surface_destroy (fish->surface);
1418 fish->surface = cdk_window_create_similar_surface (ctk_widget_get_window (widget),
1419 CAIRO_CONTENT_COLOR_ALPHA,
1420 width, height);
1421 fish->surface_width = width;
1422 fish->surface_height = height;
1423
1424 ctk_widget_queue_resize (widget);
1425
1426 g_assert (pixbuf_width != -1 && pixbuf_height != -1)do { if (pixbuf_width != -1 && pixbuf_height != -1) ;
else g_assertion_message_expr (((gchar*) 0), "fish.c", 1426,
((const char*) (__func__)), "pixbuf_width != -1 && pixbuf_height != -1"
); } while (0)
;
1427
1428 cr = cairo_create (fish->surface);
1429
1430 cairo_set_source_rgb (cr, 1, 1, 1);
1431 cairo_paint (cr);
1432
1433 cdk_cairo_set_source_pixbuf (cr, fish->pixbuf, 0, 0);
1434 pattern = cairo_get_source (cr);
1435 cairo_pattern_set_filter (pattern, CAIRO_FILTER_BEST);
1436
1437 cairo_matrix_init_identity (&matrix);
1438
1439 if (fish->april_fools) {
1440 cairo_matrix_translate (&matrix,
1441 pixbuf_width - 1, pixbuf_height - 1);
1442 cairo_matrix_rotate (&matrix, M_PI3.14159265358979323846);
1443 }
1444
1445 if (rotate) {
1446 if (fish->orientation == CAFE_PANEL_APPLET_ORIENT_RIGHT) {
1447 cairo_matrix_translate (&matrix, pixbuf_width - 1, 0);
1448 cairo_matrix_rotate (&matrix, M_PI3.14159265358979323846 * 0.5);
1449 } else {
1450 cairo_matrix_translate (&matrix, 0, pixbuf_height - 1);
1451 cairo_matrix_rotate (&matrix, M_PI3.14159265358979323846 * 1.5);
1452 }
1453 cairo_matrix_scale (&matrix,
1454 (double) (pixbuf_height - 1) / width,
1455 (double) (pixbuf_width - 1) / height);
1456 } else {
1457 cairo_matrix_scale (&matrix,
1458 (double) (pixbuf_width - 1) / width,
1459 (double) (pixbuf_height - 1) / height);
1460 }
1461
1462 cairo_pattern_set_matrix (pattern, &matrix);
1463
1464 cairo_rectangle (cr, 0, 0, width, height);
1465 cairo_fill (cr);
1466
1467 if (fish->april_fools) {
1468 cairo_set_source_rgb (cr, 1, 0.5, 0);
1469 cairo_paint_with_alpha (cr, 0.25);
1470 }
1471
1472 cairo_destroy (cr);
1473}
1474
1475static gboolean fish_applet_draw(CtkWidget* widget, cairo_t *cr, FishApplet* fish)
1476{
1477 int width, height;
1478 int src_x, src_y;
1479
1480 g_return_val_if_fail (fish->surface != NULL, FALSE)do { if ((fish->surface != ((void*)0))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "fish->surface != NULL"
); return ((0)); } } while (0)
;
1481
1482 g_assert (fish->n_frames > 0)do { if (fish->n_frames > 0) ; else g_assertion_message_expr
(((gchar*) 0), "fish.c", 1482, ((const char*) (__func__)), "fish->n_frames > 0"
); } while (0)
;
1483
1484 width = fish->surface_width;
1485 height = fish->surface_height;
1486 src_x = 0;
1487 src_y = 0;
1488
1489 if (fish->rotate) {
1490 if (fish->orientation == CAFE_PANEL_APPLET_ORIENT_RIGHT)
1491 src_y += ((height * (fish->n_frames - 1 - fish->current_frame)) / fish->n_frames);
1492 else if (fish->orientation == CAFE_PANEL_APPLET_ORIENT_LEFT)
1493 src_y += ((height * fish->current_frame) / fish->n_frames);
1494 else
1495 src_x += ((width * fish->current_frame) / fish->n_frames);
1496 } else
1497 src_x += ((width * fish->current_frame) / fish->n_frames);
1498
1499 cairo_save (cr);
1500 cairo_set_source_surface (cr, fish->surface, -src_x, -src_y);
1501 cairo_paint (cr);
1502 cairo_restore (cr);
1503
1504 return FALSE(0);
1505}
1506
1507static void fish_applet_size_allocate(CtkWidget* widget, CtkAllocation* allocation, FishApplet* fish)
1508{
1509 if (allocation->width == fish->prev_allocation.width &&
1510 allocation->height == fish->prev_allocation.height)
1511 return;
1512
1513 fish->prev_allocation = *allocation;
1514 g_idle_add (update_pixmap_in_idle, fish);
1515}
1516
1517static void fish_applet_realize(CtkWidget* widget, FishApplet* fish)
1518{
1519 if (!fish->surface)
1520 update_pixmap (fish);
1521}
1522
1523static void fish_applet_unrealize(CtkWidget* widget, FishApplet* fish)
1524{
1525 if (fish->surface)
1526 cairo_surface_destroy (fish->surface);
1527 fish->surface = NULL((void*)0);
1528 fish->surface_width = 0;
1529 fish->surface_height = 0;
1530}
1531
1532static void fish_applet_change_orient(CafePanelApplet* applet, CafePanelAppletOrient orientation)
1533{
1534 FishApplet *fish = (FishApplet *) applet;
1535
1536 if (fish->orientation == orientation)
1537 return;
1538
1539 fish->orientation = orientation;
1540
1541 if (fish->surface)
1542 update_pixmap (fish);
1543}
1544
1545static void change_water(FishApplet* fish)
1546{
1547 CtkWidget *dialog;
1548
1549 dialog = ctk_message_dialog_new (
1550 NULL((void*)0), 0, CTK_MESSAGE_INFO,
1551 CTK_BUTTONS_OK,
1552 _("The water needs changing")gettext ("The water needs changing"));
1553 ctk_message_dialog_format_secondary_text (CTK_MESSAGE_DIALOG (dialog)((((CtkMessageDialog*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((dialog)), ((ctk_message_dialog_get_type ())
)))))
,
1554 _("Look at today's date!")gettext ("Look at today's date!"));
1555 ctk_window_set_icon_name (CTK_WINDOW (dialog)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog)), ((ctk_window_get_type ()))))))
, FISH_ICON"cafe-panel-fish");
1556 ctk_window_set_screen (CTK_WINDOW (dialog)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog)), ((ctk_window_get_type ()))))))
,
1557 ctk_widget_get_screen (CTK_WIDGET (fish)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((fish)), ((ctk_widget_get_type ()))))))
));
1558
1559 ctk_widget_show_all (dialog);
1560
1561 g_signal_connect (dialog, "response",g_signal_connect_data ((dialog), ("response"), (((GCallback) (
ctk_widget_destroy))), (((void*)0)), ((void*)0), (GConnectFlags
) 0)
1562 G_CALLBACK (ctk_widget_destroy), NULL)g_signal_connect_data ((dialog), ("response"), (((GCallback) (
ctk_widget_destroy))), (((void*)0)), ((void*)0), (GConnectFlags
) 0)
;
1563}
1564
1565static gboolean handle_keypress(CtkWidget* widget, CdkEventKey* event, FishApplet* fish)
1566{
1567 switch (event->keyval) {
1568 case CDK_KEY_space0x020:
1569 case CDK_KEY_KP_Space0xff80:
1570 case CDK_KEY_Return0xff0d:
1571 case CDK_KEY_KP_Enter0xff8d:
1572 case CDK_KEY_ISO_Enter0xfe34:
1573 case CDK_KEY_3270_Enter0xfd1e:
1574 if (fish->april_fools) {
1575 change_water (fish);
1576 return TRUE(!(0));
1577 }
1578
1579 display_fortune_dialog (fish);
1580 break;
1581 default:
1582 return FALSE(0);
1583 break;
This statement is never executed
1584 }
1585
1586 return TRUE(!(0));
1587}
1588
1589static gboolean fish_enter_notify(CtkWidget* widget, CdkEventCrossing* event)
1590{
1591 FishApplet *fish;
1592 CtkWidget *event_widget;
1593
1594 fish = FISH_APPLET (widget)((((FishApplet*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), (fish_applet_get_type())))))
;
1595 event_widget = ctk_get_event_widget ((CdkEvent*) event);
1596
1597 if ((event_widget == widget) &&
1598 (event->detail != CDK_NOTIFY_INFERIOR))
1599 fish->in_applet = TRUE(!(0));
1600
1601 return FALSE(0);
1602}
1603
1604static gboolean fish_leave_notify(CtkWidget* widget, CdkEventCrossing* event)
1605{
1606 FishApplet *fish;
1607 CtkWidget *event_widget;
1608
1609 fish = FISH_APPLET (widget)((((FishApplet*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), (fish_applet_get_type())))))
;
1610 event_widget = ctk_get_event_widget ((CdkEvent*) event);
1611
1612 if ((event_widget == widget) &&
1613 (event->detail != CDK_NOTIFY_INFERIOR))
1614 fish->in_applet = FALSE(0);
1615
1616 return FALSE(0);
1617}
1618
1619static gboolean handle_button_release(FishApplet* fish, CdkEventButton* event)
1620{
1621 if (!fish->in_applet || event->button != 1)
1622 return FALSE(0);
1623
1624 if (fish->april_fools) {
1625 change_water (fish);
1626 return TRUE(!(0));
1627 }
1628
1629 display_fortune_dialog (fish);
1630
1631 return TRUE(!(0));
1632}
1633
1634static void set_tooltip(FishApplet* fish)
1635{
1636 const char *desc_format = _("%s the Fish, the fortune teller")gettext ("%s the Fish, the fortune teller");
1637 char *desc;
1638
1639 desc = g_markup_printf_escaped (desc_format, fish->name);
1640 ctk_widget_set_tooltip_markup (CTK_WIDGET (fish)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((fish)), ((ctk_widget_get_type ()))))))
, desc);
1641 g_free (desc);
1642}
1643
1644static void setup_fish_widget(FishApplet* fish)
1645{
1646 CtkWidget *widget = (CtkWidget *) fish;
1647
1648 fish->frame = ctk_frame_new (NULL((void*)0));
1649 ctk_frame_set_shadow_type (CTK_FRAME (fish->frame)((((CtkFrame*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((fish->frame)), ((ctk_frame_get_type ()))))))
, CTK_SHADOW_IN);
1650 ctk_container_add (CTK_CONTAINER (widget)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_container_get_type ()))))))
, fish->frame);
1651
1652 fish->drawing_area = ctk_drawing_area_new ();
1653 ctk_container_add (CTK_CONTAINER (fish->frame)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((fish->frame)), ((ctk_container_get_type ()))))))
, fish->drawing_area);
1654
1655 g_signal_connect (fish->drawing_area, "realize",g_signal_connect_data ((fish->drawing_area), ("realize"), (
((GCallback) (fish_applet_realize))), (fish), ((void*)0), (GConnectFlags
) 0)
1656 G_CALLBACK (fish_applet_realize), fish)g_signal_connect_data ((fish->drawing_area), ("realize"), (
((GCallback) (fish_applet_realize))), (fish), ((void*)0), (GConnectFlags
) 0)
;
1657 g_signal_connect (fish->drawing_area, "unrealize",g_signal_connect_data ((fish->drawing_area), ("unrealize")
, (((GCallback) (fish_applet_unrealize))), (fish), ((void*)0)
, (GConnectFlags) 0)
1658 G_CALLBACK (fish_applet_unrealize), fish)g_signal_connect_data ((fish->drawing_area), ("unrealize")
, (((GCallback) (fish_applet_unrealize))), (fish), ((void*)0)
, (GConnectFlags) 0)
;
1659 g_signal_connect (fish->drawing_area, "size-allocate",g_signal_connect_data ((fish->drawing_area), ("size-allocate"
), (((GCallback) (fish_applet_size_allocate))), (fish), ((void
*)0), (GConnectFlags) 0)
1660 G_CALLBACK (fish_applet_size_allocate), fish)g_signal_connect_data ((fish->drawing_area), ("size-allocate"
), (((GCallback) (fish_applet_size_allocate))), (fish), ((void
*)0), (GConnectFlags) 0)
;
1661 g_signal_connect (fish->drawing_area, "draw",g_signal_connect_data ((fish->drawing_area), ("draw"), (((
GCallback) (fish_applet_draw))), (fish), ((void*)0), (GConnectFlags
) 0)
1662 G_CALLBACK (fish_applet_draw), fish)g_signal_connect_data ((fish->drawing_area), ("draw"), (((
GCallback) (fish_applet_draw))), (fish), ((void*)0), (GConnectFlags
) 0)
;
1663
1664 ctk_widget_add_events (widget, CDK_ENTER_NOTIFY_MASK |
1665 CDK_LEAVE_NOTIFY_MASK |
1666 CDK_BUTTON_RELEASE_MASK);
1667
1668 g_signal_connect_swapped (widget, "enter_notify_event",g_signal_connect_data ((widget), ("enter_notify_event"), (((GCallback
) (fish_enter_notify))), (fish), ((void*)0), G_CONNECT_SWAPPED
)
1669 G_CALLBACK (fish_enter_notify), fish)g_signal_connect_data ((widget), ("enter_notify_event"), (((GCallback
) (fish_enter_notify))), (fish), ((void*)0), G_CONNECT_SWAPPED
)
;
1670 g_signal_connect_swapped (widget, "leave_notify_event",g_signal_connect_data ((widget), ("leave_notify_event"), (((GCallback
) (fish_leave_notify))), (fish), ((void*)0), G_CONNECT_SWAPPED
)
1671 G_CALLBACK (fish_leave_notify), fish)g_signal_connect_data ((widget), ("leave_notify_event"), (((GCallback
) (fish_leave_notify))), (fish), ((void*)0), G_CONNECT_SWAPPED
)
;
1672 g_signal_connect_swapped (widget, "button_release_event",g_signal_connect_data ((widget), ("button_release_event"), ((
(GCallback) (handle_button_release))), (fish), ((void*)0), G_CONNECT_SWAPPED
)
1673 G_CALLBACK (handle_button_release), fish)g_signal_connect_data ((widget), ("button_release_event"), ((
(GCallback) (handle_button_release))), (fish), ((void*)0), G_CONNECT_SWAPPED
)
;
1674
1675 ctk_widget_add_events (fish->drawing_area, CDK_BUTTON_RELEASE_MASK);
1676 g_signal_connect_swapped (fish->drawing_area, "button_release_event",g_signal_connect_data ((fish->drawing_area), ("button_release_event"
), (((GCallback) (handle_button_release))), (fish), ((void*)0
), G_CONNECT_SWAPPED)
1677 G_CALLBACK (handle_button_release), fish)g_signal_connect_data ((fish->drawing_area), ("button_release_event"
), (((GCallback) (handle_button_release))), (fish), ((void*)0
), G_CONNECT_SWAPPED)
;
1678
1679 load_fish_image (fish);
1680
1681 update_pixmap (fish);
1682
1683 setup_timeout (fish);
1684
1685 set_tooltip (fish);
1686 set_ally_name_desc (CTK_WIDGET (fish)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((fish)), ((ctk_widget_get_type ()))))))
, fish);
1687
1688 g_signal_connect (fish, "key_press_event",g_signal_connect_data ((fish), ("key_press_event"), (((GCallback
) (handle_keypress))), (fish), ((void*)0), (GConnectFlags) 0)
1689 G_CALLBACK (handle_keypress), fish)g_signal_connect_data ((fish), ("key_press_event"), (((GCallback
) (handle_keypress))), (fish), ((void*)0), (GConnectFlags) 0)
;
1690
1691 ctk_widget_show_all (widget);
1692}
1693
1694static const CtkActionEntry fish_menu_verbs[] = {
1695 { "FishPreferences", "document-properties", N_("_Preferences")("_Preferences"),
1696 NULL((void*)0), NULL((void*)0),
1697 G_CALLBACK (display_preferences_dialog)((GCallback) (display_preferences_dialog)) },
1698 { "FishHelp", "help-browser", N_("_Help")("_Help"),
1699 NULL((void*)0), NULL((void*)0),
1700 G_CALLBACK (display_help_dialog)((GCallback) (display_help_dialog)) },
1701 { "FishAbout", "help-about", N_("_About")("_About"),
1702 NULL((void*)0), NULL((void*)0),
1703 G_CALLBACK (display_about_dialog)((GCallback) (display_about_dialog)) }
1704};
1705
1706static gboolean fish_applet_fill(FishApplet* fish)
1707{
1708 CafePanelApplet* applet = (CafePanelApplet*) fish;
1709 CtkActionGroup* action_group;
1710
1711 fish->orientation = cafe_panel_applet_get_orient (applet);
1712
1713 setup_gsettings (fish);
1714
1715 fish->name = g_settings_get_string (fish->settings, FISH_NAME_KEY"name");
1716
1717 if (!fish->name)
1718 {
1719 fish->name = g_strdup ("Wanda")g_strdup_inline ("Wanda"); /* Fallback */
1720 }
1721
1722 fish->image = g_settings_get_string (fish->settings, FISH_IMAGE_KEY"image");
1723
1724 if (!fish->image)
1725 fish->image = g_strdup ("fishanim.png")g_strdup_inline ("fishanim.png"); /* Fallback */
1726
1727 fish->command = g_settings_get_string (fish->settings, FISH_COMMAND_KEY"command");
1728
1729 fish->n_frames = g_settings_get_int (fish->settings, FISH_FRAMES_KEY"frames");
1730
1731 if (fish->n_frames <= 0)
1732 fish->n_frames = 1;
1733
1734 fish->speed = g_settings_get_double (fish->settings, FISH_SPEED_KEY"speed");
1735
1736 fish->rotate = g_settings_get_boolean (fish->settings, FISH_ROTATE_KEY"rotate");
1737
1738 action_group = ctk_action_group_new ("Fish Applet Actions");
1739 ctk_action_group_set_translation_domain (action_group, GETTEXT_PACKAGE"cafe-panel");
1740 ctk_action_group_add_actions (action_group,
1741 fish_menu_verbs,
1742 G_N_ELEMENTS (fish_menu_verbs)(sizeof (fish_menu_verbs) / sizeof ((fish_menu_verbs)[0])),
1743 fish);
1744 cafe_panel_applet_setup_menu_from_resource (applet,
1745 FISH_RESOURCE_PATH"/org/cafe/panel/applet/fish/" "fish-menu.xml",
1746 action_group);
1747
1748 if (cafe_panel_applet_get_locked_down (applet)) {
1749 CtkAction *action;
1750
1751 action = ctk_action_group_get_action (action_group, "FishPreferences");
1752 ctk_action_set_visible (action, FALSE(0));
1753 }
1754 g_object_unref (action_group);
1755
1756 #ifndef FISH_INPROCESS
1757 ctk_window_set_default_icon_name(FISH_ICON"cafe-panel-fish");
1758 #endif
1759
1760 setup_fish_widget(fish);
1761
1762 return TRUE(!(0));
1763}
1764
1765static gboolean fishy_factory(CafePanelApplet* applet, const char* iid, gpointer data)
1766{
1767 gboolean retval = FALSE(0);
1768
1769 if (!strcmp(iid, "FishApplet"))
1770 {
1771 retval = fish_applet_fill(FISH_APPLET(applet)((((FishApplet*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((applet)), (fish_applet_get_type())))))
);
1772 }
1773
1774 return retval;
1775}
1776
1777static void fish_applet_dispose (GObject *object)
1778{
1779 FishApplet* fish = (FishApplet*) object;
1780
1781 if (fish->settings != NULL((void*)0))
1782 g_signal_handlers_disconnect_by_data (fish->settings,g_signal_handlers_disconnect_matched ((fish->settings), G_SIGNAL_MATCH_DATA
, 0, 0, ((void*)0), ((void*)0), (fish))
1783 fish)g_signal_handlers_disconnect_matched ((fish->settings), G_SIGNAL_MATCH_DATA
, 0, 0, ((void*)0), ((void*)0), (fish))
;
1784
1785 if (fish->timeout)
1786 {
1787 g_source_remove (fish->timeout);
1788 }
1789
1790 fish->timeout = 0;
1791
1792 if (fish->settings)
1793 g_object_unref (fish->settings);
1794 fish->settings = NULL((void*)0);
1795
1796 if (fish->lockdown_settings)
1797 g_object_unref (fish->lockdown_settings);
1798 fish->lockdown_settings = NULL((void*)0);
1799
1800 if (fish->name)
1801 g_free (fish->name);
1802 fish->name = NULL((void*)0);
1803
1804 if (fish->image)
1805 g_free (fish->image);
1806 fish->image = NULL((void*)0);
1807
1808 if (fish->command)
1809 g_free (fish->command);
1810 fish->command = NULL((void*)0);
1811
1812 if (fish->surface)
1813 cairo_surface_destroy (fish->surface);
1814 fish->surface = NULL((void*)0);
1815 fish->surface_width = 0;
1816 fish->surface_height = 0;
1817
1818 if (fish->pixbuf)
1819 g_object_unref (fish->pixbuf);
1820 fish->pixbuf = NULL((void*)0);
1821
1822 if (fish->preferences_dialog)
1823 ctk_widget_destroy (fish->preferences_dialog);
1824 fish->preferences_dialog = NULL((void*)0);
1825
1826 if (fish->fortune_dialog)
1827 ctk_widget_destroy (fish->fortune_dialog);
1828 fish->fortune_dialog = NULL((void*)0);
1829
1830 if (fish->source_id)
1831 g_source_remove (fish->source_id);
1832 fish->source_id = 0;
1833
1834 fish_close_channel (fish);
1835
1836 G_OBJECT_CLASS (parent_class)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((parent_class)), (((GType) ((20) << (2))))))))
->dispose (object);
1837}
1838
1839static void fish_applet_instance_init(FishApplet* fish, FishAppletClass* klass)
1840{
1841 fish->name = NULL((void*)0);
1842 fish->image = NULL((void*)0);
1843 fish->command = NULL((void*)0);
1844 fish->n_frames = 1;
1845 fish->speed = 0.0;
1846 fish->rotate = FALSE(0);
1847
1848 fish->orientation = CAFE_PANEL_APPLET_ORIENT_UP;
1849
1850 fish->frame = NULL((void*)0);
1851 fish->drawing_area = NULL((void*)0);
1852 fish->surface = NULL((void*)0);
1853 fish->timeout = 0;
1854 fish->current_frame = 0;
1855 fish->in_applet = FALSE(0);
1856
1857 fish->requisition.width = -1;
1858 fish->requisition.height = -1;
1859
1860 fish->prev_allocation.x = -1;
1861 fish->prev_allocation.y = -1;
1862 fish->prev_allocation.width = -1;
1863 fish->prev_allocation.height = -1;
1864
1865 fish->pixbuf = NULL((void*)0);
1866
1867 fish->preferences_dialog = NULL((void*)0);
1868 fish->name_entry = NULL((void*)0);
1869 fish->command_label = NULL((void*)0);
1870 fish->command_entry = NULL((void*)0);
1871 fish->preview_image = NULL((void*)0);
1872 fish->image_chooser = NULL((void*)0);
1873 fish->frames_spin = NULL((void*)0);
1874 fish->speed_spin = NULL((void*)0);
1875 fish->rotate_toggle = NULL((void*)0);
1876
1877 fish->fortune_dialog = NULL((void*)0);
1878 fish->fortune_view = NULL((void*)0);
1879 fish->fortune_label = NULL((void*)0);
1880 fish->fortune_cmd_label = NULL((void*)0);
1881 fish->fortune_buffer = NULL((void*)0);
1882
1883 fish->source_id = 0;
1884 fish->io_channel = NULL((void*)0);
1885
1886 fish->april_fools = FALSE(0);
1887
1888 cafe_panel_applet_set_flags (CAFE_PANEL_APPLET (fish)((((CafePanelApplet*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((fish)), ((cafe_panel_applet_get_type ()))))))
, CAFE_PANEL_APPLET_EXPAND_MINOR);
1889
1890 cafe_panel_applet_set_background_widget(CAFE_PANEL_APPLET(fish)((((CafePanelApplet*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((fish)), ((cafe_panel_applet_get_type ()))))))
, CTK_WIDGET(fish)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((fish)), ((ctk_widget_get_type ()))))))
);
1891}
1892
1893static void fish_applet_class_init(FishAppletClass* klass)
1894{
1895 CafePanelAppletClass* applet_class = (CafePanelAppletClass*) klass;
1896 GObjectClass *gobject_class = (GObjectClass *) klass;
1897
1898 parent_class = g_type_class_peek_parent(klass);
1899
1900 applet_class->change_orient = fish_applet_change_orient;
1901
1902 gobject_class->dispose = fish_applet_dispose;
1903
1904 init_fools_day();
1905}
1906
1907static GType fish_applet_get_type(void)
1908{
1909 static GType type = 0;
1910
1911 if (!type)
1912 {
1913 static const GTypeInfo info = {
1914 sizeof(CafePanelAppletClass),
1915 NULL((void*)0), NULL((void*)0),
1916 (GClassInitFunc) fish_applet_class_init,
1917 NULL((void*)0), NULL((void*)0),
1918 sizeof(FishApplet),
1919 0,
1920 (GInstanceInitFunc) fish_applet_instance_init,
1921 NULL((void*)0)
1922 };
1923
1924 type = g_type_register_static(PANEL_TYPE_APPLET(cafe_panel_applet_get_type ()), "FishApplet", &info, 0);
1925 }
1926
1927 return type;
1928}
1929
1930#ifdef FISH_INPROCESS
1931 CAFE_PANEL_APPLET_IN_PROCESS_FACTORY("FishAppletFactory", fish_applet_get_type(), "That-stupid-fish", fishy_factory, NULL)gboolean _cafe_panel_applet_shlib_factory (void); __attribute__
((visibility("default"))) gint _cafe_panel_applet_shlib_factory
(void) { do { bindtextdomain ("cafe-panel", "/usr/share/locale"
); bind_textdomain_codeset ("cafe-panel", "UTF-8"); if ((0)) textdomain
("cafe-panel"); } while (0); return cafe_panel_applet_factory_setup_in_process
("FishAppletFactory", fish_applet_get_type(), fishy_factory,
((void*)0)); }
1932#else
1933 CAFE_PANEL_APPLET_OUT_PROCESS_FACTORY("FishAppletFactory", fish_applet_get_type(), "That-stupid-fish", fishy_factory, NULL)int main(int argc, char* argv[]) { GOptionContext* context; GError
* error; int retval; do { bindtextdomain ("cafe-panel", "/usr/share/locale"
); bind_textdomain_codeset ("cafe-panel", "UTF-8"); if ((!(0)
)) textdomain ("cafe-panel"); } while (0); context = g_option_context_new
(""); g_option_context_add_group (context, ctk_get_option_group
((!(0)))); error = ((void*)0); if (!g_option_context_parse (context
, &argc, &argv, &error)) { if (error) { g_printerr
("Cannot parse arguments: %s.\n", error->message); g_error_free
(error); } else { g_printerr ("Cannot parse arguments.\n"); }
g_option_context_free (context); return 1; } ctk_init (&
argc, &argv); retval = cafe_panel_applet_factory_main ("FishAppletFactory"
,(!(0)), fish_applet_get_type(), fishy_factory, ((void*)0)); g_option_context_free
(context); return retval; }
1934#endif