Commit 25885840e04098aaa0cc6e3413de0aa6a884983e

Authored by Perry Werneck
1 parent 9f5a59b1

Updating macos code.

src/objects/os/macos/open.c 0 → 100644
... ... @@ -0,0 +1,163 @@
  1 +/*
  2 + * "Software pw3270, desenvolvido com base nos códigos fontes do WC3270 e X3270
  3 + * (Paul Mattes Paul.Mattes@usa.net), de emulação de terminal 3270 para acesso a
  4 + * aplicativos mainframe. Registro no INPI sob o nome G3270.
  5 + *
  6 + * Copyright (C) <2008> <Banco do Brasil S.A.>
  7 + *
  8 + * Este programa é software livre. Você pode redistribuí-lo e/ou modificá-lo sob
  9 + * os termos da GPL v.2 - Licença Pública Geral GNU, conforme publicado pela
  10 + * Free Software Foundation.
  11 + *
  12 + * Este programa é distribuído na expectativa de ser útil, mas SEM QUALQUER
  13 + * GARANTIA; sem mesmo a garantia implícita de COMERCIALIZAÇÃO ou de ADEQUAÇÃO
  14 + * A QUALQUER PROPÓSITO EM PARTICULAR. Consulte a Licença Pública Geral GNU para
  15 + * obter mais detalhes.
  16 + *
  17 + * Você deve ter recebido uma cópia da Licença Pública Geral GNU junto com este
  18 + * programa; se não, escreva para a Free Software Foundation, Inc., 51 Franklin
  19 + * St, Fifth Floor, Boston, MA 02110-1301 USA
  20 + *
  21 + * Este programa está nomeado como - e possui - linhas de código.
  22 + *
  23 + * Contatos:
  24 + *
  25 + * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck)
  26 + * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça)
  27 + *
  28 + */
  29 +
  30 +#include <config.h>
  31 +
  32 +#include <lib3270.h>
  33 +#include <lib3270/log.h>
  34 +#include <pw3270/application.h>
  35 +#include <pw3270/window.h>
  36 +#include <v3270.h>
  37 +#include <v3270/keyfile.h>
  38 +
  39 +static gchar * v3270_keyfile_find(const gchar *name) {
  40 + //
  41 + // It can be a session file, scans for it
  42 + //
  43 + const gchar * paths[] = {
  44 + g_get_user_special_dir(G_USER_DIRECTORY_DOCUMENTS),
  45 + g_get_user_config_dir()
  46 + };
  47 +
  48 + static const gchar *subdirs[] = {
  49 + "3270",
  50 + G_STRINGIFY(PRODUCT_NAME),
  51 + PACKAGE_NAME
  52 + };
  53 +
  54 + size_t path, subdir;
  55 +
  56 + g_autofree gchar * filename = g_strconcat(name,".3270",NULL);
  57 +
  58 + for(path = 0; path < G_N_ELEMENTS(paths); path++) {
  59 +
  60 + // Try subdirs.
  61 + for(subdir = 0; subdir < G_N_ELEMENTS(subdirs); subdir++) {
  62 +
  63 + gchar * fullpath = g_build_filename(paths[path],subdirs[subdir],filename,NULL);
  64 +
  65 + debug("Searching for \"%s\"",fullpath);
  66 +
  67 + if(g_file_test(fullpath,G_FILE_TEST_IS_REGULAR)) {
  68 + return fullpath;
  69 + }
  70 + g_free(fullpath);
  71 +
  72 + }
  73 +
  74 + // Try path.
  75 + {
  76 + gchar * fullpath = g_build_filename(paths[path],filename,NULL);
  77 +
  78 + debug("Searching for \"%s\"",fullpath);
  79 +
  80 + if(g_file_test(fullpath,G_FILE_TEST_IS_REGULAR)) {
  81 + return fullpath;
  82 + }
  83 + g_free(fullpath);
  84 + }
  85 +
  86 + }
  87 +
  88 + return NULL;
  89 +
  90 +}
  91 +
  92 +/// @brief Open session file
  93 +static void open(GtkApplication *application, GtkWindow **window, const gchar *filename) {
  94 +
  95 + g_message("Opening '%s'",filename);
  96 +
  97 + if(*window) {
  98 +
  99 + // Already open a window, open in new tab.
  100 + pw3270_application_window_new_tab(GTK_WIDGET(*window), filename);
  101 +
  102 + } else {
  103 + // It's a new window
  104 + *window = GTK_WINDOW(pw3270_application_window_new(application, filename));
  105 +
  106 + }
  107 +
  108 +}
  109 +
  110 +void pw3270_application_open_file(GtkApplication *application, GtkWindow **window, GFile *file) {
  111 +
  112 + g_autofree gchar * scheme = g_file_get_uri_scheme(file);
  113 +
  114 + if(g_ascii_strcasecmp(scheme,"file") == 0) {
  115 +
  116 + // It's a file scheme.
  117 + if(g_file_query_exists(file,NULL)) {
  118 +
  119 + // The file exists, load it.
  120 + g_autofree gchar *filename = g_file_get_path(file);
  121 + open(application,window,filename);
  122 +
  123 + } else {
  124 +
  125 + // Search for file.
  126 + g_autofree gchar * basename = g_file_get_basename(file);
  127 + g_autofree gchar * filename = v3270_keyfile_find(basename);
  128 +
  129 + if(filename) {
  130 + open(application,window,filename);
  131 + } else {
  132 + g_warning("Cant find session '%s'",basename);
  133 + }
  134 +
  135 + }
  136 +
  137 + } else if(g_ascii_strcasecmp(scheme,"tn3270") == 0 || g_ascii_strcasecmp(scheme,"tn3270s") == 0) {
  138 +
  139 + g_autofree gchar * uri = g_file_get_uri(file);
  140 + size_t sz = strlen(uri);
  141 +
  142 + if(sz > 0 && uri[sz-1] == '/')
  143 + uri[sz-1] = 0;
  144 +
  145 + g_message("Opening '%s' with default settings",uri);
  146 +
  147 + if(!*window) {
  148 + *window = GTK_WINDOW(pw3270_application_window_new(application, NULL));
  149 + } else {
  150 + pw3270_application_window_new_tab(GTK_WIDGET(*window), NULL);
  151 + }
  152 +
  153 + GtkWidget * terminal = pw3270_application_window_get_active_terminal(GTK_WIDGET(*window));
  154 + v3270_set_default_session(terminal);
  155 + v3270_set_url(terminal,uri);
  156 +
  157 + } else {
  158 +
  159 + g_warning("Don't know how to handle '%s' scheme",scheme);
  160 +
  161 + }
  162 +
  163 +}
... ...
src/objects/os/macos/savedesktopicon.c 0 → 100644
... ... @@ -0,0 +1,378 @@
  1 +/*
  2 + * "Software pw3270, desenvolvido com base nos códigos fontes do WC3270 e X3270
  3 + * (Paul Mattes Paul.Mattes@usa.net), de emulação de terminal 3270 para acesso a
  4 + * aplicativos mainframe. Registro no INPI sob o nome G3270.
  5 + *
  6 + * Copyright (C) <2008> <Banco do Brasil S.A.>
  7 + *
  8 + * Este programa é software livre. Você pode redistribuí-lo e/ou modificá-lo sob
  9 + * os termos da GPL v.2 - Licença Pública Geral GNU, conforme publicado pela
  10 + * Free Software Foundation.
  11 + *
  12 + * Este programa é distribuído na expectativa de ser útil, mas SEM QUALQUER
  13 + * GARANTIA; sem mesmo a garantia implícita de COMERCIALIZAÇÃO ou de ADEQUAÇÃO
  14 + * A QUALQUER PROPÓSITO EM PARTICULAR. Consulte a Licença Pública Geral GNU para
  15 + * obter mais detalhes.
  16 + *
  17 + * Você deve ter recebido uma cópia da Licença Pública Geral GNU junto com este
  18 + * programa; se não, escreva para a Free Software Foundation, Inc., 51 Franklin
  19 + * St, Fifth Floor, Boston, MA 02110-1301 USA
  20 + *
  21 + * Este programa está nomeado como - e possui - linhas de código.
  22 + *
  23 + * Contatos:
  24 + *
  25 + * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck)
  26 + * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça)
  27 + *
  28 + */
  29 +
  30 +/**
  31 + * @brief Implement Linux version of the save desktop icon action.
  32 + *
  33 + */
  34 +
  35 +#include <v3270.h>
  36 +#include <pw3270.h>
  37 +#include <pw3270/application.h>
  38 +#include <v3270/actions.h>
  39 +#include <v3270/keyfile.h>
  40 +#include <v3270/settings.h>
  41 +#include <lib3270.h>
  42 +#include <lib3270/log.h>
  43 +#include <lib3270/properties.h>
  44 +#include <v3270/tools.h>
  45 +
  46 +static GtkWidget * factory(V3270SimpleAction *action, GtkWidget *terminal);
  47 +static void response(GtkWidget *dialog, gint response_id, GtkWidget *terminal);
  48 +
  49 +static const struct _entry {
  50 +
  51 + const gchar * key;
  52 + const gchar * label;
  53 + const gchar * tooltip;
  54 + const gchar * default_value;
  55 + gint margin_top;
  56 + gint width;
  57 +
  58 +} entries[] = {
  59 +
  60 + // 0 = Shortcut name
  61 + {
  62 + .key = "Name",
  63 + .label = N_("Shortcut name"),
  64 + .default_value = G_STRINGIFY(PRODUCT_NAME),
  65 + .width = 20,
  66 + },
  67 +
  68 + // 1 = Shortcut file
  69 + {
  70 + .label = N_("Shortcut file"),
  71 + .tooltip = N_("Path for the new shortcut"),
  72 + .width = 40,
  73 + },
  74 +
  75 + // 2 = Session name
  76 + {
  77 + .label = N_("Session name"),
  78 + .margin_top = 12,
  79 + .tooltip = N_("The session name used in the window/tab title (empty for default)"),
  80 + .width = 15,
  81 + },
  82 +
  83 + // 3 = Session file
  84 + {
  85 + .label = N_("Session file"),
  86 + .tooltip = N_("The file with the session preferences for this shortcut"),
  87 + .width = 40,
  88 + },
  89 +
  90 + // 4 = Generic name.
  91 + {
  92 + .key = "GenericName",
  93 + .margin_top = 12,
  94 + .label = N_("Generic name"),
  95 + .default_value = G_STRINGIFY(PRODUCT_NAME),
  96 + .width = 20,
  97 + },
  98 +
  99 + {
  100 + .key = "Comment",
  101 + .label = N_("Comment"),
  102 + .default_value = N_("IBM 3270 Terminal emulator"),
  103 + .width = 30,
  104 + }
  105 +
  106 +};
  107 +
  108 +GAction * pw3270_action_save_desktop_icon_new(void) {
  109 +
  110 + V3270SimpleAction * action = v3270_dialog_action_new(factory);
  111 +
  112 + action->name = "save.launcher";
  113 + action->label = _("Save session shortcut");
  114 + action->tooltip = _("Create shortcut for the current session");
  115 +
  116 + return G_ACTION(action);
  117 +
  118 +}
  119 +
  120 +/*
  121 +static gchar * get_filename(GtkWidget *terminal) {
  122 +
  123 + g_autofree gchar * defname = v3270_keyfile_get_default_filename();
  124 +const gchar * current = v3270_key_file_get_filename(terminal);
  125 +
  126 +// If is not the default name, return it.
  127 +if(strcmp(defname,current)) {
  128 + return g_strdup(current);
  129 +}
  130 +
  131 +// It's the default one, create a new one on the user_config dir
  132 +g_autofree gchar * config_path = v3270_key_file_get_default_path(terminal);
  133 +
  134 +// Use the hostname
  135 +const char * hostname = lib3270_host_get_name(v3270_get_session(terminal));
  136 +if(!hostname) {
  137 + hostname = G_STRINGIFY(PRODUCT_NAME);
  138 +}
  139 +
  140 +// Build the filename
  141 +gchar *filename = g_strconcat(config_path,G_DIR_SEPARATOR_S,hostname,".3270",NULL);
  142 +
  143 +unsigned int index = 0;
  144 +while(g_file_test(filename,G_FILE_TEST_EXISTS)) {
  145 + g_free(filename);
  146 + filename = g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s.%u.3270",config_path,hostname,++index);
  147 +}
  148 +
  149 +return filename;
  150 +
  151 +}
  152 +*/
  153 +
  154 +GtkWidget * factory(V3270SimpleAction *action, GtkWidget *terminal) {
  155 +
  156 + size_t ix;
  157 +
  158 + gboolean use_header;
  159 + g_object_get(gtk_settings_get_default(), "gtk-dialogs-use-header", &use_header, NULL);
  160 +
  161 + GtkWidget * dialog =
  162 + GTK_WIDGET(g_object_new(
  163 + GTK_TYPE_DIALOG,
  164 + "use-header-bar", (use_header ? 1 : 0),
  165 + NULL
  166 + ));
  167 +
  168 +
  169 + gtk_window_set_modal(GTK_WINDOW(dialog),TRUE);
  170 + gtk_window_set_title(GTK_WINDOW(dialog),action->label);
  171 +
  172 + gtk_dialog_add_buttons(
  173 + GTK_DIALOG(dialog),
  174 + _("_Cancel"), GTK_RESPONSE_CANCEL,
  175 + _("_Save"), GTK_RESPONSE_APPLY,
  176 + NULL
  177 + );
  178 +
  179 + g_signal_connect(dialog,"response",G_CALLBACK(response),terminal);
  180 +
  181 + // Create entry fields
  182 + GtkWidget ** inputs = g_new0(GtkWidget *,G_N_ELEMENTS(entries));
  183 + g_object_set_data_full(G_OBJECT(dialog),"inputs",inputs,g_free);
  184 + debug("Dialog=%p inputs=%p",dialog,inputs);
  185 +
  186 + GtkGrid * grid = GTK_GRID(gtk_grid_new());
  187 +
  188 + gtk_box_pack_start(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dialog))),GTK_WIDGET(grid),TRUE,TRUE,0);
  189 +
  190 + // https://developer.gnome.org/hig/stable/visual-layout.html.en
  191 + gtk_container_set_border_width(GTK_CONTAINER(grid),18);
  192 + gtk_grid_set_row_spacing(GTK_GRID(grid),6);
  193 + gtk_grid_set_column_spacing(GTK_GRID(grid),12);
  194 +
  195 + // https://developer.gnome.org/hig/stable/visual-layout.html.en
  196 + // gtk_box_set_spacing(GTK_BOX(content_area),18);
  197 +
  198 + for(ix = 0; ix < G_N_ELEMENTS(entries); ix++) {
  199 +
  200 + GtkWidget * label = gtk_label_new(gettext(entries[ix].label));
  201 + gtk_label_set_xalign(GTK_LABEL(label),1);
  202 + gtk_grid_attach(grid,label,0,ix,1,1);
  203 +
  204 + inputs[ix] = gtk_entry_new();
  205 + debug("inputs[%u]=%p",(unsigned int) ix, inputs[ix]);
  206 +
  207 + if(entries[ix].margin_top) {
  208 + gtk_widget_set_margin_top(label,entries[ix].margin_top);
  209 + gtk_widget_set_margin_top(inputs[ix],entries[ix].margin_top);
  210 + }
  211 +
  212 + if(entries[ix].default_value) {
  213 + gtk_entry_set_text(GTK_ENTRY(inputs[ix]),gettext(entries[ix].default_value));
  214 + }
  215 +
  216 + if(entries[ix].tooltip) {
  217 + gtk_widget_set_tooltip_markup(GTK_WIDGET(inputs[ix]),gettext(entries[ix].tooltip));
  218 + }
  219 +
  220 + gtk_entry_set_width_chars(GTK_ENTRY(inputs[ix]),entries[ix].width);
  221 + gtk_widget_set_hexpand(inputs[ix],FALSE);
  222 + gtk_widget_set_vexpand(inputs[ix],FALSE);
  223 +
  224 + gtk_grid_attach(grid,inputs[ix],1,ix,entries[ix].width,1);
  225 +
  226 + }
  227 +
  228 + g_autofree gchar * filename = g_strdup_printf("%s/" G_STRINGIFY(PRODUCT_NAME) ".desktop",g_get_user_special_dir(G_USER_DIRECTORY_DESKTOP));
  229 +
  230 + // 1 = Shortcut filename
  231 + {
  232 + gtk_entry_set_text(GTK_ENTRY(inputs[1]),filename);
  233 + gtk_entry_bind_to_filechooser(
  234 + inputs[1],
  235 + GTK_FILE_CHOOSER_ACTION_SAVE,
  236 + _("Save to shortcut file"),
  237 + NULL,
  238 + "*.desktop",
  239 + _("Standard desktop files")
  240 + );
  241 +
  242 + }
  243 +
  244 + // 2 = Session name
  245 + {
  246 + gchar * session_name = g_strdup(v3270_get_session_name(terminal));
  247 + gchar * ptr = strchr(session_name,':');
  248 + if(ptr)
  249 + *ptr = 0;
  250 +
  251 + if(strcmp(session_name,G_STRINGIFY(PRODUCT_NAME)))
  252 + gtk_entry_set_text(GTK_ENTRY(inputs[2]),session_name);
  253 +
  254 + }
  255 +
  256 + // 3 = Session filename
  257 + {
  258 + g_autofree gchar * session_filename = v3270_key_file_build_filename(terminal);
  259 + gtk_entry_set_text(GTK_ENTRY(inputs[3]),session_filename);
  260 +
  261 + gtk_entry_bind_to_filechooser(
  262 + inputs[3],
  263 + GTK_FILE_CHOOSER_ACTION_SAVE,
  264 + _("Save to session filename"),
  265 + NULL,
  266 + "*.3270",
  267 + _("3270 session files")
  268 + );
  269 +
  270 + }
  271 +
  272 + // 4 = Generic name
  273 + gtk_entry_set_placeholder_text(GTK_ENTRY(inputs[4]),v3270_get_url(terminal));
  274 + gtk_entry_set_text(GTK_ENTRY(inputs[4]),v3270_get_url(terminal));
  275 + gtk_entry_set_input_hints(GTK_ENTRY(inputs[4]),GTK_INPUT_HINT_SPELLCHECK);
  276 +
  277 + gtk_widget_show_all(GTK_WIDGET(grid));
  278 + return dialog;
  279 +}
  280 +
  281 +static void apply(GtkWidget *dialog, GtkWidget *terminal) {
  282 +
  283 + GError * error = NULL;
  284 + size_t ix;
  285 +
  286 + static const char * key_file_data =
  287 + "[Desktop Entry]\n" \
  288 + "Icon=" G_STRINGIFY(PRODUCT_NAME) "\n" \
  289 + "Terminal=false\n" \
  290 + "Type=Application\n" \
  291 + "StartupNotify=true\n" \
  292 + "Categories=GTK;GNOME;TerminalEmulator\n" \
  293 + "OnlyShowIn=GNOME;Unity\n";
  294 +
  295 + GKeyFile * keyfile = g_key_file_new();
  296 + g_key_file_load_from_data(keyfile,key_file_data,-1,G_KEY_FILE_NONE,NULL);
  297 +
  298 +#ifdef DEBUG
  299 + {
  300 + g_autofree gchar * dbg_data = g_key_file_to_data(keyfile,NULL,NULL);
  301 + debug("\n%s\n",dbg_data);
  302 + }
  303 +#endif // DEBUG
  304 +
  305 +
  306 + GtkWidget ** inputs = g_object_get_data(G_OBJECT(dialog),"inputs");
  307 + debug("dialog=%p inputs=%p",dialog,inputs);
  308 +
  309 + for(ix = 0; ix < G_N_ELEMENTS(entries); ix++) {
  310 + if(entries[ix].key) {
  311 + debug("inputs[%u]=%p",(unsigned int) ix, inputs[ix]);
  312 + g_key_file_set_string(keyfile,"Desktop Entry",entries[ix].key,gtk_entry_get_text(GTK_ENTRY(inputs[ix])));
  313 + }
  314 + }
  315 +
  316 + // Save keyfile
  317 + v3270_key_file_save_to_file(
  318 + terminal,
  319 + gtk_entry_get_text(GTK_ENTRY(inputs[3])),
  320 + &error
  321 + );
  322 +
  323 + // Get program file name
  324 + // https://stackoverflow.com/questions/4517425/how-to-get-program-path
  325 + if(!error) {
  326 + char buffer[4096];
  327 + g_autofree gchar * pidfile = g_strdup_printf("/proc/%d/exe", getpid());
  328 +
  329 + int bytes = readlink(pidfile,buffer,4095);
  330 +
  331 + if(bytes >= 0)
  332 + buffer[bytes] = '\0';
  333 +
  334 + g_autofree gchar * exec_line =
  335 + g_strconcat(
  336 + buffer,
  337 + " \"",gtk_entry_get_text(GTK_ENTRY(inputs[3])),"\"",
  338 + NULL
  339 + );
  340 +
  341 + g_key_file_set_string(keyfile,"Desktop Entry","Exec",exec_line);
  342 +
  343 + }
  344 +
  345 + // Save shortcut
  346 + g_key_file_save_to_file(keyfile,gtk_entry_get_text(GTK_ENTRY(inputs[1])),&error);
  347 +
  348 + g_key_file_free(keyfile);
  349 +
  350 + if(error) {
  351 +
  352 + g_message("%s",error->message);
  353 + g_error_free(error);
  354 +
  355 + } else {
  356 +
  357 + // Set session name (after save to avoid changes on the old session file).
  358 + v3270_set_session_name(terminal,gtk_entry_get_text(GTK_ENTRY(inputs[2])));
  359 + v3270_emit_save_settings(terminal,NULL);
  360 +
  361 + }
  362 +
  363 +}
  364 +
  365 +void response(GtkWidget *dialog, gint response_id, GtkWidget *terminal) {
  366 +
  367 + debug("%s(%d)",__FUNCTION__,response_id);
  368 +
  369 + gtk_widget_hide(dialog);
  370 + if(response_id == GTK_RESPONSE_APPLY) {
  371 + apply(dialog,terminal);
  372 + }
  373 +
  374 + gtk_widget_destroy(dialog);
  375 +
  376 +}
  377 +
  378 +
... ...