yad/src/main.c
2026-05-18 08:10:30 +03:00

1020 lines
29 KiB
C

/*
* This file is part of YAD.
*
* YAD is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* YAD is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with YAD. If not, see <http://www.gnu.org/licenses/>.
*
* Copyright (C) 2008-2026, Victor Ananjevsky <victor@sanana.kiev.ua>
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <locale.h>
#include <stdlib.h>
#include <signal.h>
#include <stdio.h>
#include <unistd.h>
#ifndef G_OS_WIN32
# include <sys/shm.h>
# include <gdk/gdkx.h>
#endif
#include "yad.h"
YadOptions options;
GtkIconTheme *yad_icon_theme;
GdkPixbuf *big_fallback_image = NULL;
GdkPixbuf *small_fallback_image = NULL;
/* global flag for temporary disable ESC handling (needed for searchbar) */
gboolean ignore_esc = FALSE;
static GtkWidget *dialog = NULL;
static GtkWidget *text = NULL;
static gint ret = YAD_RESPONSE_ESC;
static gboolean is_x11 = FALSE;
YadNTabs *tabs;
#ifndef G_OS_WIN32
static void
sa_usr1 (gint sig)
{
if (options.plug != -1)
yad_print_result ();
else
yad_exit (options.data.def_resp);
}
static void
sa_usr2 (gint sig)
{
if (options.plug != -1)
gtk_main_quit ();
else
yad_exit (YAD_RESPONSE_CANCEL);
}
#endif
static gboolean
keys_cb (GtkWidget *w, GdkEventKey *ev, gpointer d)
{
if (options.plug != -1)
return FALSE;
switch (ev->keyval)
{
case GDK_KEY_F1:
if (options.action_data.f1)
{
run_command_async (options.action_data.f1);
return TRUE;
}
break;
case GDK_KEY_Escape:
if (!ignore_esc)
{
if (options.data.escape_ok)
yad_exit (options.data.def_resp);
else if (!options.data.no_escape)
yad_exit (YAD_RESPONSE_ESC);
return TRUE;
}
break;
case GDK_KEY_Return:
case GDK_KEY_KP_Enter:
if (ev->state & GDK_CONTROL_MASK)
{
yad_exit (options.data.def_resp);
return TRUE;
}
break;
}
return FALSE;
}
static void
btn_cb (GtkWidget *b, gchar *cmd)
{
if (cmd)
run_command_async (cmd);
else
{
gint resp = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (b), "resp"));
yad_exit (resp);
}
}
static gboolean
timeout_cb (gpointer data)
{
static guint count = 1;
GtkWidget *w = (GtkWidget *) data;
if (options.data.timeout < count)
{
yad_exit (YAD_RESPONSE_TIMEOUT);
return FALSE;
}
if (w)
{
gdouble percent = ((gdouble) options.data.timeout - count) / (gdouble) options.data.timeout;
gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (w), percent);
if (settings->show_remain)
{
gchar *lbl = g_strdup_printf (_("%d sec"), options.data.timeout - count);
gtk_progress_bar_set_text (GTK_PROGRESS_BAR (w), lbl);
g_free (lbl);
}
}
count++;
return TRUE;
}
static gboolean
unfocus_cb (GtkWidget *w, GdkEventFocus *ev, gpointer d)
{
if (options.data.close_on_unfocus)
gtk_main_quit ();
return FALSE;
}
static gboolean
link_cb (GtkLabel *l, gchar *uri, gpointer d)
{
open_uri (uri);
return TRUE;
}
void
yad_exit (gint id)
{
if ((options.mode == YAD_MODE_FILE) && !(id & 1))
{
/* show custom confirmation dialog */
if (!file_confirm_overwrite (dialog))
return;
}
ret = id;
gtk_main_quit ();
}
static GtkWidget *
create_layout (GtkWidget *dlg)
{
GtkWidget *image, *mw, *imw, *layout, *exp, *box;
layout = image = mw = exp = NULL;
/* create image */
if (options.data.dialog_image)
{
GdkPixbuf *pb = NULL;
pb = get_pixbuf (options.data.dialog_image, YAD_BIG_ICON, FALSE);
image = gtk_image_new_from_pixbuf (pb);
if (pb)
g_object_unref (pb);
gtk_widget_set_name (image, "yad-dialog-image");
gtk_widget_set_halign (image, GTK_ALIGN_CENTER);
gtk_widget_set_valign (image, GTK_ALIGN_START);
}
/* create text label */
if (options.data.dialog_text)
{
/* for dnd's tooltip we don't need text label */
if (options.mode != YAD_MODE_DND || !options.dnd_data.tooltip)
{
gchar *buf = g_strcompress (options.data.dialog_text);
text = gtk_label_new (NULL);
gtk_widget_set_name (text, "yad-dialog-label");
gtk_label_set_line_wrap (GTK_LABEL (text), TRUE);
gtk_label_set_selectable (GTK_LABEL (text), options.data.selectable_labels);
gtk_widget_set_state_flags (text, GTK_STATE_FLAG_NORMAL, FALSE);
gtk_widget_set_can_focus (text, FALSE);
if (options.data.text_width > 0)
gtk_label_set_width_chars (GTK_LABEL (text), options.data.text_width);
/* set label align and justification */
switch (options.data.text_align)
{
case GTK_JUSTIFY_LEFT:
case GTK_JUSTIFY_FILL:
gtk_label_set_xalign (GTK_LABEL (text), 0.0);
break;
case GTK_JUSTIFY_RIGHT:
gtk_label_set_xalign (GTK_LABEL (text), 1.0);
break;
case GTK_JUSTIFY_CENTER:
gtk_label_set_xalign (GTK_LABEL (text), 0.5);
break;
}
gtk_label_set_justify (GTK_LABEL (text), options.data.text_align);
if (!options.data.no_markup)
{
gtk_label_set_markup (GTK_LABEL (text), buf);
g_signal_connect (G_OBJECT (text), "activate-link", G_CALLBACK (link_cb), NULL);
}
else
gtk_label_set_text (GTK_LABEL (text), buf);
g_free (buf);
}
}
/* create main widget */
switch (options.mode)
{
case YAD_MODE_APP:
mw = app_create_widget (dlg);
break;
case YAD_MODE_CALENDAR:
mw = calendar_create_widget (dlg);
break;
case YAD_MODE_COLOR:
mw = color_create_widget (dlg);
break;
case YAD_MODE_ENTRY:
mw = entry_create_widget (dlg);
break;
case YAD_MODE_FILE:
mw = file_create_widget (dlg);
break;
case YAD_MODE_FONT:
mw = font_create_widget (dlg);
break;
case YAD_MODE_FORM:
mw = form_create_widget (dlg);
break;
#ifdef HAVE_HTML
case YAD_MODE_HTML:
mw = html_create_widget (dlg);
break;
#endif
case YAD_MODE_ICONS:
mw = icons_create_widget (dlg);
break;
case YAD_MODE_LIST:
mw = list_create_widget (dlg);
break;
case YAD_MODE_NOTEBOOK:
if (options.plug == -1)
mw = notebook_create_widget (dlg);
break;
case YAD_MODE_PANED:
if (options.plug == -1)
mw = paned_create_widget (dlg);
break;
case YAD_MODE_PICTURE:
mw = picture_create_widget (dlg);
break;
case YAD_MODE_PROGRESS:
mw = progress_create_widget (dlg);
break;
case YAD_MODE_SCALE:
mw = scale_create_widget (dlg);
break;
case YAD_MODE_TEXTINFO:
mw = text_create_widget (dlg);
break;
default: ;
}
/* add expander */
if (mw && options.data.expander)
{
imw = exp = gtk_expander_new_with_mnemonic (options.data.expander);
gtk_expander_set_expanded (GTK_EXPANDER (exp), FALSE);
gtk_container_add (GTK_CONTAINER (exp), mw);
}
else
imw = mw;
/* create layout */
layout = gtk_box_new (GTK_ORIENTATION_VERTICAL, 5);
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5);
if (image)
gtk_box_pack_start (GTK_BOX (box), image, FALSE, FALSE, 2);
if (text)
gtk_box_pack_start (GTK_BOX (box), text, TRUE, TRUE, 2);
gtk_box_pack_start (GTK_BOX (layout), box, FALSE, FALSE, 0);
if (imw)
{
if (options.mode == YAD_MODE_ENTRY)
gtk_box_pack_start (GTK_BOX (layout), imw, TRUE, FALSE, 0);
else
gtk_box_pack_start (GTK_BOX (layout), imw, TRUE, TRUE, 0);
}
if (options.mode == YAD_MODE_DND)
dnd_init (layout);
return layout;
}
static void
realize_cb (GtkWidget *dlg, gpointer d)
{
GdkGravity gravity = GDK_GRAVITY_NORTH_WEST;
if (options.data.fixed)
{
gtk_widget_set_size_request (dlg, options.data.width, options.data.height);
gtk_window_set_resizable (GTK_WINDOW (dlg), !options.data.fixed);
}
else
{
gint cw, ch;
/* get current window size for gtk_window_resize */
gtk_window_get_size (GTK_WINDOW (dlg), &cw, &ch);
if (options.data.width == -1)
options.data.width = cw;
if (options.data.height == -1)
options.data.height = ch;
gtk_window_resize (GTK_WINDOW (dlg), options.data.width, options.data.height);
}
if (options.data.use_posx || options.data.use_posy)
{
gint ww, wh, sw, sh;
gtk_window_get_size (GTK_WINDOW (dlg), &ww, &wh);
gdk_window_get_geometry (gdk_get_default_root_window (), NULL, NULL, &sw, &sh);
/* place window to specified coordinates */
if (!options.data.use_posx)
gtk_window_get_position (GTK_WINDOW (dlg), &options.data.posx, NULL);
if (!options.data.use_posy)
gtk_window_get_position (GTK_WINDOW (dlg), NULL, &options.data.posy);
if (options.data.negx)
{
options.data.posx = sw - ww + options.data.posx;
gravity = GDK_GRAVITY_NORTH_EAST;
}
if (options.data.negy)
{
options.data.posy = sh - wh + options.data.posy;
gravity = GDK_GRAVITY_SOUTH_WEST;
}
if (options.data.negx && options.data.negy)
gravity = GDK_GRAVITY_SOUTH_EAST;
gtk_window_set_gravity (GTK_WINDOW (dlg), gravity);
gtk_window_move (GTK_WINDOW (dlg), options.data.posx, options.data.posy);
}
}
static GtkWidget *
create_dialog (void)
{
GtkWidget *dlg, *vbox, *layout;
/* create dialog window */
dlg = gtk_window_new (GTK_WINDOW_TOPLEVEL);
#ifdef DEPRECATED
if (options.data.splash)
options.data.window_type = GDK_WINDOW_TYPE_HINT_SPLASHSCREEN;
#endif
gtk_window_set_type_hint (GTK_WINDOW (dlg), options.data.window_type);
gtk_window_set_title (GTK_WINDOW (dlg), options.data.dialog_title);
gtk_widget_set_name (dlg, "yad-dialog-window");
g_signal_connect (G_OBJECT (dlg), "delete-event", G_CALLBACK (gtk_main_quit), NULL);
g_signal_connect (G_OBJECT (dlg), "key-press-event", G_CALLBACK (keys_cb), NULL);
g_signal_connect (G_OBJECT (dlg), "focus-out-event", G_CALLBACK (unfocus_cb), NULL);
/* set window icon */
if (options.data.window_icon)
{
if (g_file_test (options.data.window_icon, G_FILE_TEST_EXISTS))
gtk_window_set_icon_from_file (GTK_WINDOW (dlg), options.data.window_icon, NULL);
else
gtk_window_set_icon_name (GTK_WINDOW (dlg), options.data.window_icon);
}
else
gtk_window_set_icon_name (GTK_WINDOW (dlg), "yad");
/* set window borders */
if (options.data.borders < 0)
options.data.borders = 2;
gtk_container_set_border_width (GTK_CONTAINER (dlg), (guint) options.data.borders);
/* set window size and position */
if (!options.data.maximized && !options.data.fullscreen)
{
if (options.data.center)
gtk_window_set_position (GTK_WINDOW (dlg), GTK_WIN_POS_CENTER_ALWAYS);
else if (options.data.mouse)
gtk_window_set_position (GTK_WINDOW (dlg), GTK_WIN_POS_MOUSE);
}
/* set window behavior */
if (options.data.sticky)
gtk_window_stick (GTK_WINDOW (dlg));
gtk_window_set_keep_above (GTK_WINDOW (dlg), options.data.ontop);
gtk_window_set_decorated (GTK_WINDOW (dlg), !options.data.undecorated);
gtk_window_set_skip_taskbar_hint (GTK_WINDOW (dlg), options.data.skip_taskbar);
gtk_window_set_skip_pager_hint (GTK_WINDOW (dlg), options.data.skip_taskbar);
gtk_window_set_accept_focus (GTK_WINDOW (dlg), options.data.focus);
/* create box */
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 2);
gtk_container_add (GTK_CONTAINER (dlg), vbox);
layout = create_layout (dlg);
/* create timeout indicator widget */
if (options.data.timeout)
{
GtkWidget *cbox = NULL, *topb = NULL;
if (G_LIKELY (options.data.to_indicator) && strcasecmp (options.data.to_indicator, "none") != 0)
{
topb = gtk_progress_bar_new ();
gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (topb), 1.0);
gtk_widget_set_name (topb, "yad-timeout-indicator");
}
/* add timeout indicator */
if (topb)
{
if (strcasecmp (options.data.to_indicator, "top") == 0)
{
gtk_orientable_set_orientation (GTK_ORIENTABLE (topb), GTK_ORIENTATION_HORIZONTAL);
cbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
gtk_box_pack_start (GTK_BOX (cbox), topb, FALSE, FALSE, 2);
gtk_box_pack_end (GTK_BOX (cbox), layout, TRUE, TRUE, 0);
}
else if (strcasecmp (options.data.to_indicator, "bottom") == 0)
{
gtk_orientable_set_orientation (GTK_ORIENTABLE (topb), GTK_ORIENTATION_HORIZONTAL);
cbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
gtk_box_pack_start (GTK_BOX (cbox), layout, TRUE, TRUE, 0);
gtk_box_pack_end (GTK_BOX (cbox), topb, FALSE, FALSE, 2);
}
else if (strcasecmp (options.data.to_indicator, "left") == 0)
{
gtk_orientable_set_orientation (GTK_ORIENTABLE (topb), GTK_ORIENTATION_VERTICAL);
gtk_progress_bar_set_inverted (GTK_PROGRESS_BAR (topb), TRUE);
cbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
gtk_box_pack_start (GTK_BOX (cbox), topb, FALSE, FALSE, 2);
gtk_box_pack_end (GTK_BOX (cbox), layout, TRUE, TRUE, 0);
}
else if (strcasecmp (options.data.to_indicator, "right") == 0)
{
gtk_orientable_set_orientation (GTK_ORIENTABLE (topb), GTK_ORIENTATION_VERTICAL);
gtk_progress_bar_set_inverted (GTK_PROGRESS_BAR (topb), TRUE);
cbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
gtk_box_pack_start (GTK_BOX (cbox), layout, TRUE, TRUE, 0);
gtk_box_pack_end (GTK_BOX (cbox), topb, FALSE, FALSE, 2);
}
if (settings->show_remain)
{
gchar *lbl = g_strdup_printf (_("%d sec"), options.data.timeout);
gtk_progress_bar_set_show_text (GTK_PROGRESS_BAR (topb), TRUE);
gtk_progress_bar_set_text (GTK_PROGRESS_BAR (topb), lbl);
g_free (lbl);
}
}
else
{
cbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
gtk_box_pack_start (GTK_BOX (cbox), layout, TRUE, TRUE, 0);
}
if (cbox)
gtk_box_pack_start (GTK_BOX (vbox), cbox, TRUE, TRUE, 0);
/* set timeout handler */
g_timeout_add_seconds (1, timeout_cb, topb);
}
else
gtk_box_pack_start (GTK_BOX (vbox), layout, TRUE, TRUE, 0);
#ifdef HAVE_HTML
/* enable no-buttons mode if --browser is specified and sets no custom buttons */
if (options.mode == YAD_MODE_HTML && options.html_data.browser && !options.data.buttons)
options.data.no_buttons = TRUE;
#endif
if (!options.data.no_buttons)
{
GtkWidget *btn;
/* create buttons container */
GtkWidget *bbox = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL);
gtk_box_set_homogeneous (GTK_BOX (bbox), TRUE);
gtk_container_set_border_width (GTK_CONTAINER (bbox), 2);
gtk_box_set_spacing (GTK_BOX (bbox), 5);
gtk_button_box_set_layout (GTK_BUTTON_BOX (bbox), options.data.buttons_layout);
/* add buttons */
if (options.data.buttons)
{
GSList *tmp = options.data.buttons;
do
{
YadButton *b = (YadButton *) tmp->data;
btn = gtk_button_new ();
gtk_container_add (GTK_CONTAINER (btn), get_label (b->name, 2, btn));
g_object_set_data (G_OBJECT (btn), "resp", GINT_TO_POINTER (b->response));
g_signal_connect (G_OBJECT (btn), "clicked", G_CALLBACK (btn_cb), b->cmd);
gtk_box_pack_start (GTK_BOX (bbox), btn, TRUE, TRUE, 0);
tmp = tmp->next;
}
while (tmp != NULL);
}
else
{
if (options.mode == YAD_MODE_PROGRESS || options.mode == YAD_MODE_DND || options.mode == YAD_MODE_PICTURE)
{
/* add close button */
btn = gtk_button_new ();
gtk_container_add (GTK_CONTAINER (btn), get_label ("yad-close", 2, btn));
g_object_set_data (G_OBJECT (btn), "resp", GINT_TO_POINTER (YAD_RESPONSE_OK));
g_signal_connect (G_OBJECT (btn), "clicked", G_CALLBACK (btn_cb), NULL);
gtk_box_pack_start (GTK_BOX (bbox), btn, TRUE, TRUE, 0);
}
else
{
/* add cancel button */
btn = gtk_button_new ();
gtk_container_add (GTK_CONTAINER (btn), get_label ("yad-cancel", 2, btn));
g_object_set_data (G_OBJECT (btn), "resp", GINT_TO_POINTER (YAD_RESPONSE_CANCEL));
g_signal_connect (G_OBJECT (btn), "clicked", G_CALLBACK (btn_cb), NULL);
gtk_box_pack_start (GTK_BOX (bbox), btn, TRUE, TRUE, 0);
/*add ok button */
btn = gtk_button_new ();
gtk_container_add (GTK_CONTAINER (btn), get_label ("yad-ok", 2, btn));
g_object_set_data (G_OBJECT (btn), "resp", GINT_TO_POINTER (YAD_RESPONSE_OK));
g_signal_connect (G_OBJECT (btn), "clicked", G_CALLBACK (btn_cb), NULL);
gtk_box_pack_start (GTK_BOX (bbox), btn, TRUE, TRUE, 0);
}
}
/* add buttons box to main window */
gtk_box_pack_start (GTK_BOX (vbox), bbox, FALSE, FALSE, 0);
}
/* show widgets */
gtk_widget_show_all (vbox);
/* parse geometry or move window, if given. must be after showing widget */
if (!options.data.maximized && !options.data.fullscreen)
{
parse_geometry ();
g_signal_connect (G_OBJECT (dlg), "realize", G_CALLBACK (realize_cb), NULL);
gtk_widget_show_all (dlg);
}
else
{
gtk_widget_show (dlg);
/* set maximized or fixed size after showing widget */
if (options.data.maximized)
gtk_window_maximize (GTK_WINDOW (dlg));
else if (options.data.fullscreen)
gtk_window_fullscreen (GTK_WINDOW (dlg));
}
/* print xid */
if (is_x11 && options.print_xid)
{
FILE *xf;
if (options.xid_file)
xf = fopen (options.xid_file, "w");
else
xf = stderr;
if (xf)
{
fprintf (xf, "0x%lX\n", GDK_WINDOW_XID (gtk_widget_get_window (dlg)));
if (options.xid_file)
fclose (xf);
else
fflush (xf);
}
}
return dlg;
}
static void
create_plug (void)
{
GtkWidget *win, *box;
tabs = get_tabs (options.plug, FALSE);
while (!tabs)
{
usleep (1000);
tabs = get_tabs (options.plug, FALSE);
}
while (!tabs[0].xid)
usleep (1000);
win = gtk_plug_new (0);
/* set window borders */
if (options.data.borders == -1)
options.data.borders = (gint) gtk_container_get_border_width (GTK_CONTAINER (win));
gtk_container_set_border_width (GTK_CONTAINER (win), (guint) options.data.borders);
box = create_layout (win);
if (box)
gtk_container_add (GTK_CONTAINER (win), box);
gtk_widget_show_all (win);
/* add plug data */
/* notebook/paned will count non-zero xids */
tabs[options.tabnum].pid = getpid ();
tabs[options.tabnum].xid = gtk_plug_get_id (GTK_PLUG (win));
shmdt (tabs);
}
void
yad_print_result (void)
{
switch (options.mode)
{
case YAD_MODE_APP:
app_print_result ();
break;
case YAD_MODE_CALENDAR:
calendar_print_result ();
break;
case YAD_MODE_COLOR:
color_print_result ();
break;
case YAD_MODE_ENTRY:
entry_print_result ();
break;
case YAD_MODE_FILE:
file_print_result ();
break;
case YAD_MODE_FONT:
font_print_result ();
break;
case YAD_MODE_FORM:
form_print_result ();
break;
case YAD_MODE_LIST:
list_print_result ();
break;
case YAD_MODE_NOTEBOOK:
notebook_print_result ();
break;
case YAD_MODE_PANED:
paned_print_result ();
break;
case YAD_MODE_SCALE:
scale_print_result ();
break;
case YAD_MODE_TEXTINFO:
text_print_result ();
break;
default:;
}
}
gint
main (gint argc, gchar ** argv)
{
GOptionContext *ctx;
GError *err = NULL;
gint w, h;
gchar *str;
setlocale (LC_ALL, "");
#ifdef ENABLE_NLS
bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
textdomain (GETTEXT_PACKAGE);
#endif
gtk_init (&argc, &argv);
g_set_application_name ("YAD");
yad_load_settings ();
yad_icon_theme = gtk_icon_theme_get_default ();
yad_options_init ();
ctx = yad_create_context ();
/* parse YAD_OPTIONS */
if (g_getenv ("YAD_OPTIONS"))
{
gchar *cmd, **args = NULL;
gint cnt;
cmd = g_strdup_printf ("yad %s", g_getenv ("YAD_OPTIONS"));
if (g_shell_parse_argv (cmd, &cnt, &args, &err))
{
g_option_context_parse (ctx, &cnt, &args, &err);
if (err)
{
g_printerr (_("Unable to parse YAD_OPTIONS: %s\n"), err->message);
g_error_free (err);
err = NULL;
}
}
else
{
g_printerr (_("Unable to parse YAD_OPTIONS: %s\n"), err->message);
g_error_free (err);
err = NULL;
}
g_free (cmd);
}
/* parse command line */
g_option_context_parse (ctx, &argc, &argv, &err);
if (err)
{
g_printerr (_("Unable to parse command line: %s\n"), err->message);
return -1;
}
if (write_settings)
{
yad_write_settings ();
return 0;
}
#ifdef DEPRECATED
if (options.data.splash)
{
if (options.debug)
g_printerr(_("WARNING: Using splash option is deprecated, please use --window-type instead"));
}
#endif
yad_set_mode ();
/* set working directory */
if (options.data.workdir)
{
if (g_chdir (options.data.workdir) != 0)
g_printerr (_("Unable to change directory to %s: %s\n"),
options.data.workdir, strerror (errno));
}
/* check for current GDK backend */
#ifdef GDK_WINDOWING_X11
if (GDK_IS_X11_DISPLAY (gdk_display_get_default ()))
is_x11 = TRUE;
#endif
/* parse custom css */
if (options.css)
{
GtkCssProvider *css = gtk_css_provider_new ();
if (g_file_test (options.css, G_FILE_TEST_EXISTS))
gtk_css_provider_load_from_path (css, options.css, NULL);
else
gtk_css_provider_load_from_data (css, options.css, -1, NULL);
gtk_style_context_add_provider_for_screen (gdk_screen_get_default (), GTK_STYLE_PROVIDER (css),
GTK_STYLE_PROVIDER_PRIORITY_USER);
g_object_unref (css);
}
#ifdef DEPRECATED
else if (options.gtkrc_file)
{
GtkCssProvider *css = gtk_css_provider_new ();
if (options.debug)
g_printerr (_("WARNING: Using gtkrc option is deprecated, please use --css instead\n"));
gtk_css_provider_load_from_path (css, options.gtkrc_file, NULL);
gtk_style_context_add_provider_for_screen (gdk_screen_get_default (), GTK_STYLE_PROVIDER (css),
GTK_STYLE_PROVIDER_PRIORITY_USER);
g_object_unref (css);
}
#endif
/* set default icons and icon theme */
if (options.data.icon_theme)
gtk_icon_theme_set_custom_theme (yad_icon_theme, options.data.icon_theme);
gtk_icon_size_lookup (GTK_ICON_SIZE_DIALOG, &w, &h);
big_fallback_image = gtk_icon_theme_load_icon (yad_icon_theme, "yad", MIN (w, h),
GTK_ICON_LOOKUP_GENERIC_FALLBACK, NULL);
gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, &w, &h);
small_fallback_image = gtk_icon_theme_load_icon (yad_icon_theme, "yad", MIN (w, h),
GTK_ICON_LOOKUP_GENERIC_FALLBACK, NULL);
/* correct separators */
str = g_strcompress (options.common_data.separator);
options.common_data.separator = str;
str = g_strcompress (options.common_data.item_separator);
options.common_data.item_separator = str;
/* loads an extra arguments, if specified */
if (options.rest_file)
{
GIOChannel *ioc;
gchar *buf;
guint len, line = 0;
g_strfreev (options.extra_data);
options.extra_data = NULL;
ioc = g_io_channel_new_file (options.rest_file, "r", NULL);
while (TRUE)
{
gint status = g_io_channel_read_line (ioc, &buf, NULL, NULL, NULL);
if (status != G_IO_STATUS_NORMAL)
break;
/* remove \n at the end of string */
len = strlen (buf);
if (buf[len - 1] == '\n')
buf[len - 1] = '\0';
/* add line to arguments array */
options.extra_data = g_realloc (options.extra_data, (line + 2) * sizeof (gchar *));
options.extra_data[line] = g_strcompress (buf);
options.extra_data[line + 1] = NULL;
g_free (buf);
line++;
}
g_io_channel_shutdown (ioc, FALSE, NULL);
}
#ifndef G_OS_WIN32
/* add YAD_PID variable */
str = g_strdup_printf ("%d", getpid ());
g_setenv ("YAD_PID", str, TRUE);
/* set signal handlers */
signal (SIGUSR1, sa_usr1);
signal (SIGUSR2, sa_usr2);
signal (SIGTERM, sa_usr2); /* Clean exit on SIGTERM */
signal (SIGINT, sa_usr2); /* Clean exit on SIGINT (Ctrl+C) */
#endif
if (!is_x11 && options.plug != -1)
{
options.plug = -1;
if (options.debug)
g_printerr (_("WARNING: --plug mode not supported outside X11\n"));
}
/* plug mode */
if (options.plug != -1)
{
create_plug ();
gtk_main ();
shmdt (tabs);
return ret;
}
if (!is_x11)
{
if (options.mode == YAD_MODE_NOTEBOOK || options.mode == YAD_MODE_PANED
#ifdef HAVE_TRAY
|| options.mode == YAD_MODE_NOTIFICATION
#endif
)
{
g_printerr (_("WARNING: This mode not supported outside X11\n"));
return 1;
}
}
switch (options.mode)
{
case YAD_MODE_ABOUT:
ret = yad_about ();
break;
case YAD_MODE_VERSION:
g_print ("%s (GTK+ %d.%d.%d)\n", VERSION, gtk_major_version, gtk_minor_version, gtk_micro_version);
break;
#ifdef HAVE_TRAY
case YAD_MODE_NOTIFICATION:
ret = yad_notification_run ();
break;
#endif
#ifdef HAVE_APPINDICATOR
case YAD_MODE_APPINDICATOR:
ret = yad_appindicator_run ();
break;
#endif
case YAD_MODE_POPUP:
if (!options.popup_data.keep)
{
/* set timeout handler (must be before runiing popup) */
if (options.data.timeout == 0)
options.data.timeout = YAD_POPUP_TIMEOUT;
g_timeout_add_seconds (1, timeout_cb, NULL);
}
ret = yad_popup_run ();
break;
case YAD_MODE_PRINT:
ret = yad_print_run ();
break;
default:
dialog = create_dialog ();
if (is_x11)
{
/* add YAD_XID variable */
str = g_strdup_printf ("0x%lX", GDK_WINDOW_XID (gtk_widget_get_window (dialog)));
g_setenv ("YAD_XID", str, TRUE);
}
/* make some specific init actions */
if (options.mode == YAD_MODE_NOTEBOOK)
notebook_swallow_childs ();
else if (options.mode == YAD_MODE_PANED)
paned_swallow_childs ();
else if (options.mode == YAD_MODE_TEXTINFO)
text_goto_line ();
else if (options.mode == YAD_MODE_PICTURE)
{
if (options.picture_data.size == YAD_PICTURE_FIT)
picture_fit_to_window ();
}
if (text && options.data.selectable_labels)
gtk_label_select_region (GTK_LABEL (text), 0, 0);
/* run main loop */
gtk_main ();
/* print results */
if (ret != YAD_RESPONSE_TIMEOUT && ret != YAD_RESPONSE_ESC)
{
if (options.data.always_print)
yad_print_result ();
else
{
/* standard OK button pressed */
if (ret == YAD_RESPONSE_OK && options.data.buttons == NULL)
yad_print_result ();
/* custom even button pressed */
else if (!(ret & 1))
yad_print_result ();
}
}
#ifndef G_OS_WIN32
if (options.mode == YAD_MODE_NOTEBOOK)
notebook_close_childs ();
else if (options.mode == YAD_MODE_PANED)
paned_close_childs ();
/* autokill option for progress dialog */
if (!options.kill_parent)
{
if (options.mode == YAD_MODE_PROGRESS && options.progress_data.autokill && ret != YAD_RESPONSE_OK)
kill (getppid (), SIGHUP);
}
#endif
}
#ifndef G_OS_WIN32
/* NSIG defined in signal.h */
if (options.kill_parent > 0 && options.kill_parent < NSIG)
kill (getppid (), options.kill_parent);
#endif
return ret;
}