Commit bc786932e5d28a63bc544cc032714c088491976f

Authored by Perry Werneck
1 parent dbbac7ef

Reorganizing folders to avoid confusion with the object window and OS

windows.
@@ -38,7 +38,7 @@ SOURCES= \ @@ -38,7 +38,7 @@ SOURCES= \
38 $(wildcard src/objects/terminal/*.c) \ 38 $(wildcard src/objects/terminal/*.c) \
39 $(wildcard src/objects/toolbar/*.c) \ 39 $(wildcard src/objects/toolbar/*.c) \
40 $(wildcard src/objects/settings/*.c) \ 40 $(wildcard src/objects/settings/*.c) \
41 - $(wildcard src/objects/@OSNAME@/*.c) \ 41 + $(wildcard src/objects/os/@OSNAME@/*.c) \
42 $(wildcard src/main/*.c) \ 42 $(wildcard src/main/*.c) \
43 $(wildcard src/main/@OSNAME@/*.c) \ 43 $(wildcard src/main/@OSNAME@/*.c) \
44 $(wildcard src/main/@OSNAME@/*.rc) \ 44 $(wildcard src/main/@OSNAME@/*.rc) \
src/objects/linux/savedesktopicon.c
@@ -1,308 +0,0 @@ @@ -1,308 +0,0 @@
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 <lib3270.h>  
41 - #include <lib3270/log.h>  
42 -  
43 - static GtkWidget * factory(V3270SimpleAction *action, GtkWidget *terminal);  
44 - static void response(GtkWidget *dialog, gint response_id, GtkWidget *terminal);  
45 -  
46 -/*  
47 -  
48 -[Desktop Entry]  
49 -GenericName=pw3270  
50 -Name=pw3270  
51 -Comment=Comment  
52 -Exec=/usr/bin/sisbb  
53 -Icon=pw3270  
54 -Terminal=false  
55 -Type=Application  
56 -StartupNotify=true  
57 -Categories=GTK;GNOME;TerminalEmulator  
58 -OnlyShowIn=GNOME;Unity  
59 -X-Desktop-File-Install-Version=0.23  
60 -*/  
61 -  
62 - static const struct _entry {  
63 -  
64 - const gchar * key;  
65 - const gchar * label;  
66 - const gchar * tooltip;  
67 - const gchar * default_value;  
68 - gint width;  
69 -// gint n_chars;  
70 -  
71 - } entries[] = {  
72 -  
73 - {  
74 - .label = N_("File name"),  
75 - .width = 40,  
76 - },  
77 -  
78 - {  
79 - .key = "Name",  
80 - .label = N_("Launcher name"),  
81 - .default_value = G_STRINGIFY(PRODUCT_NAME),  
82 - .width = 20,  
83 - },  
84 -  
85 - {  
86 - .key = "GenericName",  
87 - .label = N_("Generic name"),  
88 - .default_value = G_STRINGIFY(PRODUCT_NAME),  
89 - .width = 20,  
90 - },  
91 -  
92 - {  
93 - .key = "Comment",  
94 - .label = N_("Comment"),  
95 - .default_value = N_("IBM 3270 Terminal emulator"),  
96 - .width = 30,  
97 - }  
98 -  
99 - };  
100 -  
101 - GAction * pw3270_action_save_desktop_icon_new(void) {  
102 -  
103 - V3270SimpleAction * action = v3270_dialog_action_new(factory);  
104 -  
105 - action->name = "save.launcher";  
106 - action->label = _("Save desktop icon");  
107 - action->tooltip = _("Create a desktop icon for the current session");  
108 -  
109 - return G_ACTION(action);  
110 -  
111 - }  
112 -  
113 - GtkWidget * factory(V3270SimpleAction *action, GtkWidget *terminal) {  
114 -  
115 - size_t ix;  
116 -  
117 - gboolean use_header;  
118 - g_object_get(gtk_settings_get_default(), "gtk-dialogs-use-header", &use_header, NULL);  
119 -  
120 - GtkWidget * dialog =  
121 - GTK_WIDGET(g_object_new(  
122 - GTK_TYPE_DIALOG,  
123 - "use-header-bar", (use_header ? 1 : 0),  
124 - NULL  
125 - ));  
126 -  
127 -  
128 - gtk_window_set_modal(GTK_WINDOW(dialog),TRUE);  
129 - gtk_window_set_title(GTK_WINDOW(dialog),action->label);  
130 -  
131 - gtk_dialog_add_buttons(  
132 - GTK_DIALOG(dialog),  
133 - _("_Cancel"), GTK_RESPONSE_CANCEL,  
134 - _("_Save"), GTK_RESPONSE_APPLY,  
135 - NULL  
136 - );  
137 -  
138 - g_signal_connect(dialog,"response",G_CALLBACK(response),terminal);  
139 -  
140 - // Create entry fields  
141 - GtkWidget ** inputs = g_new0(GtkWidget *,G_N_ELEMENTS(entries));  
142 - g_object_set_data_full(G_OBJECT(dialog),"inputs",inputs,g_free);  
143 - debug("Dialog=%p inputs=%p",dialog,inputs);  
144 -  
145 - GtkGrid * grid = GTK_GRID(gtk_grid_new());  
146 -  
147 - gtk_box_pack_start(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dialog))),GTK_WIDGET(grid),TRUE,TRUE,0);  
148 -  
149 - // https://developer.gnome.org/hig/stable/visual-layout.html.en  
150 - gtk_container_set_border_width(GTK_CONTAINER(grid),18);  
151 - gtk_grid_set_row_spacing(GTK_GRID(grid),6);  
152 - gtk_grid_set_column_spacing(GTK_GRID(grid),12);  
153 -  
154 - // https://developer.gnome.org/hig/stable/visual-layout.html.en  
155 - // gtk_box_set_spacing(GTK_BOX(content_area),18);  
156 -  
157 - for(ix = 0; ix < G_N_ELEMENTS(entries); ix++) {  
158 -  
159 - GtkWidget * label = gtk_label_new(gettext(entries[ix].label));  
160 - gtk_label_set_xalign(GTK_LABEL(label),1);  
161 - gtk_grid_attach(grid,label,0,ix,1,1);  
162 -  
163 - inputs[ix] = gtk_entry_new();  
164 - debug("inputs[%u]=%p",(unsigned int) ix, inputs[ix]);  
165 -  
166 - if(entries[ix].default_value) {  
167 - gtk_entry_set_text(GTK_ENTRY(inputs[ix]),gettext(entries[ix].default_value));  
168 - }  
169 -  
170 - gtk_entry_set_width_chars(GTK_ENTRY(inputs[ix]),entries[ix].width);  
171 -// gtk_entry_set_max_width_chars(GTK_ENTRY(inputs[ix]),entries[ix].n_chars);  
172 - gtk_widget_set_hexpand(inputs[ix],FALSE);  
173 - gtk_widget_set_vexpand(inputs[ix],FALSE);  
174 -  
175 - gtk_grid_attach(grid,inputs[ix],1,ix,entries[ix].width,1);  
176 -  
177 - }  
178 -  
179 - g_autofree gchar * filename = g_strdup_printf("%s/" G_STRINGIFY(PRODUCT_NAME) ".desktop",g_get_user_special_dir(G_USER_DIRECTORY_DESKTOP));  
180 -  
181 - gtk_entry_set_text(GTK_ENTRY(inputs[0]),filename);  
182 -  
183 - /*  
184 - gtk_entry_set_placeholder_text(GTK_ENTRY(inputs[1]),G_STRINGIFY(PRODUCT_NAME));  
185 - gtk_entry_set_text(GTK_ENTRY(inputs[1]),G_STRINGIFY(PRODUCT_NAME));  
186 -  
187 - gtk_entry_set_placeholder_text(GTK_ENTRY(inputs[2]),G_STRINGIFY(PRODUCT_NAME));  
188 - gtk_entry_set_text(GTK_ENTRY(inputs[2]),G_STRINGIFY(PRODUCT_NAME));  
189 - */  
190 -  
191 - gtk_entry_set_placeholder_text(GTK_ENTRY(inputs[3]),v3270_get_url(terminal));  
192 - gtk_entry_set_text(GTK_ENTRY(inputs[3]),v3270_get_url(terminal));  
193 - gtk_entry_set_input_hints(GTK_ENTRY(inputs[3]),GTK_INPUT_HINT_SPELLCHECK);  
194 -  
195 - gtk_widget_show_all(GTK_WIDGET(grid));  
196 - return dialog;  
197 - }  
198 -  
199 - void response(GtkWidget *dialog, gint response_id, GtkWidget *terminal) {  
200 -  
201 - debug("%s(%d)",__FUNCTION__,response_id);  
202 -  
203 - if(response_id == GTK_RESPONSE_APPLY) {  
204 -  
205 - static const char * key_file_data =  
206 - "[Desktop Entry]\n" \  
207 - "Icon=" G_STRINGIFY(PRODUCT_NAME) "\n" \  
208 - "Terminal=false\n" \  
209 - "Type=Application\n" \  
210 - "StartupNotify=true\n" \  
211 - "Categories=GTK;GNOME;TerminalEmulator\n" \  
212 - "OnlyShowIn=GNOME;Unity\n";  
213 -  
214 - GError * error = NULL;  
215 - size_t ix;  
216 -  
217 - GKeyFile * keyfile = g_key_file_new();  
218 - g_key_file_load_from_data(keyfile,key_file_data,-1,G_KEY_FILE_NONE,NULL);  
219 -  
220 -#ifdef DEBUG  
221 - {  
222 - g_autofree gchar * dbg_data = g_key_file_to_data(keyfile,NULL,NULL);  
223 - debug("\n%s\n",dbg_data);  
224 - }  
225 -#endif // DEBUG  
226 -  
227 -  
228 - GtkWidget ** inputs = g_object_get_data(G_OBJECT(dialog),"inputs");  
229 - debug("dialog=%p inputs=%p",dialog,inputs);  
230 -  
231 - for(ix = 0; ix < G_N_ELEMENTS(entries); ix++) {  
232 - if(entries[ix].key) {  
233 - debug("inputs[%u]=%p",(unsigned int) ix, inputs[ix]);  
234 - g_key_file_set_string(keyfile,"Desktop Entry",entries[ix].key,gtk_entry_get_text(GTK_ENTRY(inputs[ix])));  
235 - }  
236 - }  
237 -  
238 - // Get session filename  
239 - /*  
240 - const gchar * session_file = v3270_get_session_filename(terminal);  
241 -  
242 - if(!session_file) {  
243 -  
244 - // No session file, create one.  
245 -  
246 - // Check for configdir  
247 - g_autofree gchar * configdir = g_build_filename(g_get_user_config_dir(),G_STRINGIFY(PRODUCT_NAME),"sessions",NULL);  
248 - g_mkdir_with_parents(configdir,0755);  
249 -  
250 - // Create a base name  
251 - g_autofree gchar * basename = g_path_get_basename(gtk_entry_get_text(GTK_ENTRY(inputs[0])));  
252 -  
253 - gchar *ptr = strrchr(basename,'.');  
254 - if(ptr)  
255 - *ptr = 0;  
256 -  
257 - ix = time(NULL);  
258 - gchar * new_session_file = g_strdup_printf("%s/%s.3270",configdir,basename);  
259 - while(!g_file_test(new_session_file,G_FILE_TEST_EXISTS)) {  
260 - g_free(new_session_file);  
261 - new_session_file = g_strdup_printf("%s/%s_%08lx.3270",configdir,basename,(unsigned long) ix++);  
262 - }  
263 -  
264 - g_message("Saving session to %s",new_session_file);  
265 - v3270_set_session_filename(terminal,new_session_file);  
266 - g_free(new_session_file);  
267 -  
268 - }  
269 - */  
270 -  
271 - // Get program file name  
272 - // https://stackoverflow.com/questions/4517425/how-to-get-program-path  
273 - {  
274 - char buffer[4096];  
275 - g_autofree gchar * pidfile = g_strdup_printf("/proc/%d/exe", getpid());  
276 -  
277 - int bytes = readlink(pidfile,buffer,4095);  
278 -  
279 - if(bytes >= 0)  
280 - buffer[bytes] = '\0';  
281 -  
282 - g_autofree gchar * exec_line = g_strdup_printf("%s \"%s\"",buffer,v3270_key_file_get_file_name(terminal));  
283 - g_key_file_set_string(keyfile,"Desktop Entry","Exec",exec_line);  
284 -  
285 - }  
286 -  
287 - g_key_file_save_to_file(keyfile,gtk_entry_get_text(GTK_ENTRY(inputs[0])),&error);  
288 -  
289 - if(error) {  
290 -  
291 - g_message("%s",error->message);  
292 -  
293 -  
294 - g_error_free(error);  
295 -  
296 - } else {  
297 -  
298 - g_message("File \"%s\" was saved",gtk_entry_get_text(GTK_ENTRY(inputs[0])));  
299 -  
300 - }  
301 -  
302 -  
303 - g_key_file_free(keyfile);  
304 - }  
305 -  
306 - gtk_widget_destroy(dialog);  
307 -  
308 -}  
src/objects/os/linux/savedesktopicon.c 0 → 100644
@@ -0,0 +1,308 @@ @@ -0,0 +1,308 @@
  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 <lib3270.h>
  41 + #include <lib3270/log.h>
  42 +
  43 + static GtkWidget * factory(V3270SimpleAction *action, GtkWidget *terminal);
  44 + static void response(GtkWidget *dialog, gint response_id, GtkWidget *terminal);
  45 +
  46 +/*
  47 +
  48 +[Desktop Entry]
  49 +GenericName=pw3270
  50 +Name=pw3270
  51 +Comment=Comment
  52 +Exec=/usr/bin/sisbb
  53 +Icon=pw3270
  54 +Terminal=false
  55 +Type=Application
  56 +StartupNotify=true
  57 +Categories=GTK;GNOME;TerminalEmulator
  58 +OnlyShowIn=GNOME;Unity
  59 +X-Desktop-File-Install-Version=0.23
  60 +*/
  61 +
  62 + static const struct _entry {
  63 +
  64 + const gchar * key;
  65 + const gchar * label;
  66 + const gchar * tooltip;
  67 + const gchar * default_value;
  68 + gint width;
  69 +// gint n_chars;
  70 +
  71 + } entries[] = {
  72 +
  73 + {
  74 + .label = N_("File name"),
  75 + .width = 40,
  76 + },
  77 +
  78 + {
  79 + .key = "Name",
  80 + .label = N_("Launcher name"),
  81 + .default_value = G_STRINGIFY(PRODUCT_NAME),
  82 + .width = 20,
  83 + },
  84 +
  85 + {
  86 + .key = "GenericName",
  87 + .label = N_("Generic name"),
  88 + .default_value = G_STRINGIFY(PRODUCT_NAME),
  89 + .width = 20,
  90 + },
  91 +
  92 + {
  93 + .key = "Comment",
  94 + .label = N_("Comment"),
  95 + .default_value = N_("IBM 3270 Terminal emulator"),
  96 + .width = 30,
  97 + }
  98 +
  99 + };
  100 +
  101 + GAction * pw3270_action_save_desktop_icon_new(void) {
  102 +
  103 + V3270SimpleAction * action = v3270_dialog_action_new(factory);
  104 +
  105 + action->name = "save.launcher";
  106 + action->label = _("Save desktop icon");
  107 + action->tooltip = _("Create a desktop icon for the current session");
  108 +
  109 + return G_ACTION(action);
  110 +
  111 + }
  112 +
  113 + GtkWidget * factory(V3270SimpleAction *action, GtkWidget *terminal) {
  114 +
  115 + size_t ix;
  116 +
  117 + gboolean use_header;
  118 + g_object_get(gtk_settings_get_default(), "gtk-dialogs-use-header", &use_header, NULL);
  119 +
  120 + GtkWidget * dialog =
  121 + GTK_WIDGET(g_object_new(
  122 + GTK_TYPE_DIALOG,
  123 + "use-header-bar", (use_header ? 1 : 0),
  124 + NULL
  125 + ));
  126 +
  127 +
  128 + gtk_window_set_modal(GTK_WINDOW(dialog),TRUE);
  129 + gtk_window_set_title(GTK_WINDOW(dialog),action->label);
  130 +
  131 + gtk_dialog_add_buttons(
  132 + GTK_DIALOG(dialog),
  133 + _("_Cancel"), GTK_RESPONSE_CANCEL,
  134 + _("_Save"), GTK_RESPONSE_APPLY,
  135 + NULL
  136 + );
  137 +
  138 + g_signal_connect(dialog,"response",G_CALLBACK(response),terminal);
  139 +
  140 + // Create entry fields
  141 + GtkWidget ** inputs = g_new0(GtkWidget *,G_N_ELEMENTS(entries));
  142 + g_object_set_data_full(G_OBJECT(dialog),"inputs",inputs,g_free);
  143 + debug("Dialog=%p inputs=%p",dialog,inputs);
  144 +
  145 + GtkGrid * grid = GTK_GRID(gtk_grid_new());
  146 +
  147 + gtk_box_pack_start(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dialog))),GTK_WIDGET(grid),TRUE,TRUE,0);
  148 +
  149 + // https://developer.gnome.org/hig/stable/visual-layout.html.en
  150 + gtk_container_set_border_width(GTK_CONTAINER(grid),18);
  151 + gtk_grid_set_row_spacing(GTK_GRID(grid),6);
  152 + gtk_grid_set_column_spacing(GTK_GRID(grid),12);
  153 +
  154 + // https://developer.gnome.org/hig/stable/visual-layout.html.en
  155 + // gtk_box_set_spacing(GTK_BOX(content_area),18);
  156 +
  157 + for(ix = 0; ix < G_N_ELEMENTS(entries); ix++) {
  158 +
  159 + GtkWidget * label = gtk_label_new(gettext(entries[ix].label));
  160 + gtk_label_set_xalign(GTK_LABEL(label),1);
  161 + gtk_grid_attach(grid,label,0,ix,1,1);
  162 +
  163 + inputs[ix] = gtk_entry_new();
  164 + debug("inputs[%u]=%p",(unsigned int) ix, inputs[ix]);
  165 +
  166 + if(entries[ix].default_value) {
  167 + gtk_entry_set_text(GTK_ENTRY(inputs[ix]),gettext(entries[ix].default_value));
  168 + }
  169 +
  170 + gtk_entry_set_width_chars(GTK_ENTRY(inputs[ix]),entries[ix].width);
  171 +// gtk_entry_set_max_width_chars(GTK_ENTRY(inputs[ix]),entries[ix].n_chars);
  172 + gtk_widget_set_hexpand(inputs[ix],FALSE);
  173 + gtk_widget_set_vexpand(inputs[ix],FALSE);
  174 +
  175 + gtk_grid_attach(grid,inputs[ix],1,ix,entries[ix].width,1);
  176 +
  177 + }
  178 +
  179 + g_autofree gchar * filename = g_strdup_printf("%s/" G_STRINGIFY(PRODUCT_NAME) ".desktop",g_get_user_special_dir(G_USER_DIRECTORY_DESKTOP));
  180 +
  181 + gtk_entry_set_text(GTK_ENTRY(inputs[0]),filename);
  182 +
  183 + /*
  184 + gtk_entry_set_placeholder_text(GTK_ENTRY(inputs[1]),G_STRINGIFY(PRODUCT_NAME));
  185 + gtk_entry_set_text(GTK_ENTRY(inputs[1]),G_STRINGIFY(PRODUCT_NAME));
  186 +
  187 + gtk_entry_set_placeholder_text(GTK_ENTRY(inputs[2]),G_STRINGIFY(PRODUCT_NAME));
  188 + gtk_entry_set_text(GTK_ENTRY(inputs[2]),G_STRINGIFY(PRODUCT_NAME));
  189 + */
  190 +
  191 + gtk_entry_set_placeholder_text(GTK_ENTRY(inputs[3]),v3270_get_url(terminal));
  192 + gtk_entry_set_text(GTK_ENTRY(inputs[3]),v3270_get_url(terminal));
  193 + gtk_entry_set_input_hints(GTK_ENTRY(inputs[3]),GTK_INPUT_HINT_SPELLCHECK);
  194 +
  195 + gtk_widget_show_all(GTK_WIDGET(grid));
  196 + return dialog;
  197 + }
  198 +
  199 + void response(GtkWidget *dialog, gint response_id, GtkWidget *terminal) {
  200 +
  201 + debug("%s(%d)",__FUNCTION__,response_id);
  202 +
  203 + if(response_id == GTK_RESPONSE_APPLY) {
  204 +
  205 + static const char * key_file_data =
  206 + "[Desktop Entry]\n" \
  207 + "Icon=" G_STRINGIFY(PRODUCT_NAME) "\n" \
  208 + "Terminal=false\n" \
  209 + "Type=Application\n" \
  210 + "StartupNotify=true\n" \
  211 + "Categories=GTK;GNOME;TerminalEmulator\n" \
  212 + "OnlyShowIn=GNOME;Unity\n";
  213 +
  214 + GError * error = NULL;
  215 + size_t ix;
  216 +
  217 + GKeyFile * keyfile = g_key_file_new();
  218 + g_key_file_load_from_data(keyfile,key_file_data,-1,G_KEY_FILE_NONE,NULL);
  219 +
  220 +#ifdef DEBUG
  221 + {
  222 + g_autofree gchar * dbg_data = g_key_file_to_data(keyfile,NULL,NULL);
  223 + debug("\n%s\n",dbg_data);
  224 + }
  225 +#endif // DEBUG
  226 +
  227 +
  228 + GtkWidget ** inputs = g_object_get_data(G_OBJECT(dialog),"inputs");
  229 + debug("dialog=%p inputs=%p",dialog,inputs);
  230 +
  231 + for(ix = 0; ix < G_N_ELEMENTS(entries); ix++) {
  232 + if(entries[ix].key) {
  233 + debug("inputs[%u]=%p",(unsigned int) ix, inputs[ix]);
  234 + g_key_file_set_string(keyfile,"Desktop Entry",entries[ix].key,gtk_entry_get_text(GTK_ENTRY(inputs[ix])));
  235 + }
  236 + }
  237 +
  238 + // Get session filename
  239 + /*
  240 + const gchar * session_file = v3270_get_session_filename(terminal);
  241 +
  242 + if(!session_file) {
  243 +
  244 + // No session file, create one.
  245 +
  246 + // Check for configdir
  247 + g_autofree gchar * configdir = g_build_filename(g_get_user_config_dir(),G_STRINGIFY(PRODUCT_NAME),"sessions",NULL);
  248 + g_mkdir_with_parents(configdir,0755);
  249 +
  250 + // Create a base name
  251 + g_autofree gchar * basename = g_path_get_basename(gtk_entry_get_text(GTK_ENTRY(inputs[0])));
  252 +
  253 + gchar *ptr = strrchr(basename,'.');
  254 + if(ptr)
  255 + *ptr = 0;
  256 +
  257 + ix = time(NULL);
  258 + gchar * new_session_file = g_strdup_printf("%s/%s.3270",configdir,basename);
  259 + while(!g_file_test(new_session_file,G_FILE_TEST_EXISTS)) {
  260 + g_free(new_session_file);
  261 + new_session_file = g_strdup_printf("%s/%s_%08lx.3270",configdir,basename,(unsigned long) ix++);
  262 + }
  263 +
  264 + g_message("Saving session to %s",new_session_file);
  265 + v3270_set_session_filename(terminal,new_session_file);
  266 + g_free(new_session_file);
  267 +
  268 + }
  269 + */
  270 +
  271 + // Get program file name
  272 + // https://stackoverflow.com/questions/4517425/how-to-get-program-path
  273 + {
  274 + char buffer[4096];
  275 + g_autofree gchar * pidfile = g_strdup_printf("/proc/%d/exe", getpid());
  276 +
  277 + int bytes = readlink(pidfile,buffer,4095);
  278 +
  279 + if(bytes >= 0)
  280 + buffer[bytes] = '\0';
  281 +
  282 + g_autofree gchar * exec_line = g_strdup_printf("%s \"%s\"",buffer,v3270_key_file_get_file_name(terminal));
  283 + g_key_file_set_string(keyfile,"Desktop Entry","Exec",exec_line);
  284 +
  285 + }
  286 +
  287 + g_key_file_save_to_file(keyfile,gtk_entry_get_text(GTK_ENTRY(inputs[0])),&error);
  288 +
  289 + if(error) {
  290 +
  291 + g_message("%s",error->message);
  292 +
  293 +
  294 + g_error_free(error);
  295 +
  296 + } else {
  297 +
  298 + g_message("File \"%s\" was saved",gtk_entry_get_text(GTK_ENTRY(inputs[0])));
  299 +
  300 + }
  301 +
  302 +
  303 + g_key_file_free(keyfile);
  304 + }
  305 +
  306 + gtk_widget_destroy(dialog);
  307 +
  308 +}
src/objects/os/windows/savedesktopicon.c 0 → 100644
@@ -0,0 +1,273 @@ @@ -0,0 +1,273 @@
  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 Windows version of the save desktop icon action.
  32 + *
  33 + * References:
  34 + *
  35 + * <https://stackoverflow.com/questions/3906974/how-to-programmatically-create-a-shortcut-using-win32>
  36 + * <https://docs.microsoft.com/pt-br/windows/win32/shell/links?redirectedfrom=MSDN>
  37 + *
  38 + */
  39 +
  40 +// #include <stdafx.h>
  41 + #include <winsock2.h>
  42 + #include <windows.h>
  43 + #include <winnls.h>
  44 + #include <shobjidl.h>
  45 + #include <objbase.h>
  46 + #include <objidl.h>
  47 + #include <shlguid.h>
  48 +
  49 + #include <v3270.h>
  50 + #include <pw3270.h>
  51 + #include <pw3270/application.h>
  52 + #include <v3270/actions.h>
  53 + #include <lib3270.h>
  54 + #include <lib3270/log.h>
  55 +
  56 + static GtkWidget * factory(V3270SimpleAction *action, GtkWidget *terminal);
  57 + static void response(GtkWidget *dialog, gint response_id, GtkWidget *terminal);
  58 +
  59 + static const struct _entry {
  60 +
  61 + const gchar * label;
  62 + const gchar * tooltip;
  63 + gint width;
  64 +
  65 + } entries[] = {
  66 +
  67 + {
  68 + .label = N_("Launcher name"),
  69 + .width = 40,
  70 + },
  71 +
  72 + {
  73 + .label = N_("Description"),
  74 + .width = 20,
  75 + }
  76 +
  77 + };
  78 +
  79 + GAction * pw3270_action_save_desktop_icon_new(void) {
  80 +
  81 + V3270SimpleAction * action = v3270_dialog_action_new(factory);
  82 +
  83 + action->name = "save.launcher";
  84 + action->label = _("Save desktop icon");
  85 + action->tooltip = _("Create a desktop icon for the current session");
  86 +
  87 + return G_ACTION(action);
  88 +
  89 + }
  90 +
  91 + GtkWidget * factory(V3270SimpleAction *action, GtkWidget *terminal) {
  92 +
  93 + size_t ix;
  94 +
  95 + gboolean use_header;
  96 + g_object_get(gtk_settings_get_default(), "gtk-dialogs-use-header", &use_header, NULL);
  97 +
  98 + GtkWidget * dialog =
  99 + GTK_WIDGET(g_object_new(
  100 + GTK_TYPE_DIALOG,
  101 + "use-header-bar", (use_header ? 1 : 0),
  102 + NULL
  103 + ));
  104 +
  105 + gtk_window_set_modal(GTK_WINDOW(dialog),TRUE);
  106 + gtk_window_set_title(GTK_WINDOW(dialog),action->label);
  107 +
  108 + gtk_dialog_add_buttons(
  109 + GTK_DIALOG(dialog),
  110 + _("_Cancel"), GTK_RESPONSE_CANCEL,
  111 + _("_Save"), GTK_RESPONSE_APPLY,
  112 + NULL
  113 + );
  114 +
  115 + g_signal_connect(dialog,"response",G_CALLBACK(response),terminal);
  116 +
  117 + // Create entry fields
  118 + GtkWidget ** inputs = g_new0(GtkWidget *,G_N_ELEMENTS(entries));
  119 + g_object_set_data_full(G_OBJECT(dialog),"inputs",inputs,g_free);
  120 + debug("Dialog=%p inputs=%p",dialog,inputs);
  121 +
  122 + GtkGrid * grid = GTK_GRID(gtk_grid_new());
  123 +
  124 + gtk_box_pack_start(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dialog))),GTK_WIDGET(grid),TRUE,TRUE,0);
  125 +
  126 + // https://developer.gnome.org/hig/stable/visual-layout.html.en
  127 + gtk_container_set_border_width(GTK_CONTAINER(grid),18);
  128 + gtk_grid_set_row_spacing(GTK_GRID(grid),6);
  129 + gtk_grid_set_column_spacing(GTK_GRID(grid),12);
  130 +
  131 + for(ix = 0; ix < G_N_ELEMENTS(entries); ix++) {
  132 +
  133 + GtkWidget * label = gtk_label_new(gettext(entries[ix].label));
  134 + gtk_label_set_xalign(GTK_LABEL(label),1);
  135 + gtk_grid_attach(grid,label,0,ix,1,1);
  136 +
  137 + inputs[ix] = gtk_entry_new();
  138 + debug("inputs[%u]=%p",(unsigned int) ix, inputs[ix]);
  139 +
  140 + gtk_entry_set_width_chars(GTK_ENTRY(inputs[ix]),entries[ix].width);
  141 + gtk_widget_set_hexpand(inputs[ix],FALSE);
  142 + gtk_widget_set_vexpand(inputs[ix],FALSE);
  143 +
  144 + gtk_grid_attach(grid,inputs[ix],1,ix,entries[ix].width,1);
  145 +
  146 + }
  147 +
  148 + {
  149 + gchar * filename = g_strdup_printf(
  150 + "%s\\" G_STRINGIFY(PRODUCT_NAME) ".lnk",
  151 + g_get_user_special_dir(G_USER_DIRECTORY_DESKTOP)
  152 + );
  153 +
  154 + size_t ix = 0;
  155 +
  156 + while(g_file_test(filename,G_FILE_TEST_EXISTS)) {
  157 +
  158 + g_free(filename);
  159 + filename = g_strdup_printf(
  160 + "%s\\" G_STRINGIFY(PRODUCT_NAME) "%u.lnk",
  161 + g_get_user_special_dir(G_USER_DIRECTORY_DESKTOP),
  162 + (unsigned int) ++ix
  163 + );
  164 +
  165 + }
  166 +
  167 + gtk_entry_set_text(GTK_ENTRY(inputs[0]),filename);
  168 + g_free(filename);
  169 + }
  170 +
  171 + gtk_widget_show_all(GTK_WIDGET(grid));
  172 + return dialog;
  173 + }
  174 +
  175 + static HRESULT CreateShortCut(LPSTR pszTargetfile, LPSTR pszTargetargs, LPSTR pszLinkfile, LPSTR pszDescription, int iShowmode, LPSTR pszCurdir, LPSTR pszIconfile, int iIconindex) {
  176 +
  177 + // https://www.codeproject.com/Articles/11467/How-to-create-short-cuts-link-files
  178 + IShellLink* pShellLink; // IShellLink object pointer
  179 + IPersistFile* pPersistFile; // IPersistFile object pointer
  180 + WORD wszLinkfile[MAX_PATH]; // pszLinkfile as Unicode string
  181 + int iWideCharsWritten; // Number of wide characters written
  182 +
  183 + HRESULT hRes =
  184 + CoCreateInstance(
  185 + &CLSID_ShellLink, // predefined CLSID of the IShellLink object
  186 + NULL, // pointer to parent interface if part of aggregate
  187 + CLSCTX_INPROC_SERVER, // caller and called code are in same process
  188 + &IID_IShellLink, // predefined interface of the IShellLink object
  189 + (void **) &pShellLink); // Returns a pointer to the IShellLink object
  190 +
  191 + if(!SUCCEEDED(hRes)) {
  192 + return hRes;
  193 + }
  194 +
  195 + if(pszTargetfile && strlen(pszTargetfile)) {
  196 + hRes = pShellLink->lpVtbl->SetPath(pShellLink,pszTargetfile);
  197 + } else {
  198 + char filename[MAX_PATH+1];
  199 + memset(filename,0,MAX_PATH+1);
  200 + GetModuleFileName(NULL,filename,MAX_PATH);
  201 + hRes = pShellLink->lpVtbl->SetPath(pShellLink,filename);
  202 + }
  203 +
  204 + if(pszTargetargs) {
  205 + hRes = pShellLink->lpVtbl->SetArguments(pShellLink,pszTargetargs);
  206 + } else {
  207 + hRes = pShellLink->lpVtbl->SetArguments(pShellLink,"");
  208 + }
  209 +
  210 + if(pszDescription && strlen(pszDescription) > 0) {
  211 + hRes = pShellLink->lpVtbl->SetDescription(pShellLink,pszDescription);
  212 + } else {
  213 + hRes = pShellLink->lpVtbl->SetDescription(pShellLink,_("IBM 3270 Terminal emulator"));
  214 + }
  215 +
  216 + if(iShowmode > 0) {
  217 + hRes = pShellLink->lpVtbl->SetShowCmd(pShellLink,iShowmode);
  218 + }
  219 +
  220 + if(pszCurdir && strlen(pszCurdir) > 0) {
  221 + hRes = pShellLink->lpVtbl->SetWorkingDirectory(pShellLink,pszCurdir);
  222 + } else {
  223 + g_autofree gchar * appdir = g_win32_get_package_installation_directory_of_module(NULL);
  224 + hRes = pShellLink->lpVtbl->SetWorkingDirectory(pShellLink,appdir);
  225 + }
  226 +
  227 + if(pszIconfile && strlen(pszIconfile) > 0 && iIconindex >= 0) {
  228 + hRes = pShellLink->lpVtbl->SetIconLocation(pShellLink, pszIconfile, iIconindex);
  229 + }
  230 +
  231 + // Use the IPersistFile object to save the shell link
  232 + hRes = pShellLink->lpVtbl->QueryInterface(
  233 + pShellLink, // existing IShellLink object
  234 + &IID_IPersistFile, // pre-defined interface of the IPersistFile object
  235 + (void **) &pPersistFile); // returns a pointer to the IPersistFile object
  236 +
  237 +
  238 + if(SUCCEEDED(hRes)){
  239 + iWideCharsWritten = MultiByteToWideChar(CP_ACP, 0, pszLinkfile, -1, wszLinkfile, MAX_PATH);
  240 + hRes = pPersistFile->lpVtbl->Save(pPersistFile,wszLinkfile, TRUE);
  241 + pPersistFile->lpVtbl->Release(pPersistFile);
  242 + }
  243 +
  244 + pShellLink->lpVtbl->Release(pShellLink);
  245 +
  246 + return hRes;
  247 + }
  248 +
  249 + void response(GtkWidget *dialog, gint response_id, GtkWidget *terminal) {
  250 +
  251 + debug("%s(%d)",__FUNCTION__,response_id);
  252 +
  253 + if(response_id == GTK_RESPONSE_APPLY) {
  254 +
  255 + // Save desktop icon
  256 + GtkWidget ** inputs = g_object_get_data(G_OBJECT(dialog),"inputs");
  257 +
  258 + HRESULT hRes = CreateShortCut(
  259 + NULL, // LPSTR pszTargetfile,
  260 + v3270_key_file_get_file_name(terminal), // LPSTR pszTargetargs,
  261 + gtk_entry_get_text(GTK_ENTRY(inputs[0])), // LPSTR pszLinkfile,
  262 + gtk_entry_get_text(GTK_ENTRY(inputs[1])), //LPSTR pszDescription,
  263 + 0,
  264 + NULL,
  265 + NULL,
  266 + 0
  267 + );
  268 +
  269 + }
  270 +
  271 + gtk_widget_destroy(dialog);
  272 +
  273 +}
src/objects/windows/savedesktopicon.c
@@ -1,273 +0,0 @@ @@ -1,273 +0,0 @@
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 Windows version of the save desktop icon action.  
32 - *  
33 - * References:  
34 - *  
35 - * <https://stackoverflow.com/questions/3906974/how-to-programmatically-create-a-shortcut-using-win32>  
36 - * <https://docs.microsoft.com/pt-br/windows/win32/shell/links?redirectedfrom=MSDN>  
37 - *  
38 - */  
39 -  
40 -// #include <stdafx.h>  
41 - #include <winsock2.h>  
42 - #include <windows.h>  
43 - #include <winnls.h>  
44 - #include <shobjidl.h>  
45 - #include <objbase.h>  
46 - #include <objidl.h>  
47 - #include <shlguid.h>  
48 -  
49 - #include <v3270.h>  
50 - #include <pw3270.h>  
51 - #include <pw3270/application.h>  
52 - #include <v3270/actions.h>  
53 - #include <lib3270.h>  
54 - #include <lib3270/log.h>  
55 -  
56 - static GtkWidget * factory(V3270SimpleAction *action, GtkWidget *terminal);  
57 - static void response(GtkWidget *dialog, gint response_id, GtkWidget *terminal);  
58 -  
59 - static const struct _entry {  
60 -  
61 - const gchar * label;  
62 - const gchar * tooltip;  
63 - gint width;  
64 -  
65 - } entries[] = {  
66 -  
67 - {  
68 - .label = N_("Launcher name"),  
69 - .width = 40,  
70 - },  
71 -  
72 - {  
73 - .label = N_("Description"),  
74 - .width = 20,  
75 - }  
76 -  
77 - };  
78 -  
79 - GAction * pw3270_action_save_desktop_icon_new(void) {  
80 -  
81 - V3270SimpleAction * action = v3270_dialog_action_new(factory);  
82 -  
83 - action->name = "save.launcher";  
84 - action->label = _("Save desktop icon");  
85 - action->tooltip = _("Create a desktop icon for the current session");  
86 -  
87 - return G_ACTION(action);  
88 -  
89 - }  
90 -  
91 - GtkWidget * factory(V3270SimpleAction *action, GtkWidget *terminal) {  
92 -  
93 - size_t ix;  
94 -  
95 - gboolean use_header;  
96 - g_object_get(gtk_settings_get_default(), "gtk-dialogs-use-header", &use_header, NULL);  
97 -  
98 - GtkWidget * dialog =  
99 - GTK_WIDGET(g_object_new(  
100 - GTK_TYPE_DIALOG,  
101 - "use-header-bar", (use_header ? 1 : 0),  
102 - NULL  
103 - ));  
104 -  
105 - gtk_window_set_modal(GTK_WINDOW(dialog),TRUE);  
106 - gtk_window_set_title(GTK_WINDOW(dialog),action->label);  
107 -  
108 - gtk_dialog_add_buttons(  
109 - GTK_DIALOG(dialog),  
110 - _("_Cancel"), GTK_RESPONSE_CANCEL,  
111 - _("_Save"), GTK_RESPONSE_APPLY,  
112 - NULL  
113 - );  
114 -  
115 - g_signal_connect(dialog,"response",G_CALLBACK(response),terminal);  
116 -  
117 - // Create entry fields  
118 - GtkWidget ** inputs = g_new0(GtkWidget *,G_N_ELEMENTS(entries));  
119 - g_object_set_data_full(G_OBJECT(dialog),"inputs",inputs,g_free);  
120 - debug("Dialog=%p inputs=%p",dialog,inputs);  
121 -  
122 - GtkGrid * grid = GTK_GRID(gtk_grid_new());  
123 -  
124 - gtk_box_pack_start(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dialog))),GTK_WIDGET(grid),TRUE,TRUE,0);  
125 -  
126 - // https://developer.gnome.org/hig/stable/visual-layout.html.en  
127 - gtk_container_set_border_width(GTK_CONTAINER(grid),18);  
128 - gtk_grid_set_row_spacing(GTK_GRID(grid),6);  
129 - gtk_grid_set_column_spacing(GTK_GRID(grid),12);  
130 -  
131 - for(ix = 0; ix < G_N_ELEMENTS(entries); ix++) {  
132 -  
133 - GtkWidget * label = gtk_label_new(gettext(entries[ix].label));  
134 - gtk_label_set_xalign(GTK_LABEL(label),1);  
135 - gtk_grid_attach(grid,label,0,ix,1,1);  
136 -  
137 - inputs[ix] = gtk_entry_new();  
138 - debug("inputs[%u]=%p",(unsigned int) ix, inputs[ix]);  
139 -  
140 - gtk_entry_set_width_chars(GTK_ENTRY(inputs[ix]),entries[ix].width);  
141 - gtk_widget_set_hexpand(inputs[ix],FALSE);  
142 - gtk_widget_set_vexpand(inputs[ix],FALSE);  
143 -  
144 - gtk_grid_attach(grid,inputs[ix],1,ix,entries[ix].width,1);  
145 -  
146 - }  
147 -  
148 - {  
149 - gchar * filename = g_strdup_printf(  
150 - "%s\\" G_STRINGIFY(PRODUCT_NAME) ".lnk",  
151 - g_get_user_special_dir(G_USER_DIRECTORY_DESKTOP)  
152 - );  
153 -  
154 - size_t ix = 0;  
155 -  
156 - while(g_file_test(filename,G_FILE_TEST_EXISTS)) {  
157 -  
158 - g_free(filename);  
159 - filename = g_strdup_printf(  
160 - "%s\\" G_STRINGIFY(PRODUCT_NAME) "%u.lnk",  
161 - g_get_user_special_dir(G_USER_DIRECTORY_DESKTOP),  
162 - (unsigned int) ++ix  
163 - );  
164 -  
165 - }  
166 -  
167 - gtk_entry_set_text(GTK_ENTRY(inputs[0]),filename);  
168 - g_free(filename);  
169 - }  
170 -  
171 - gtk_widget_show_all(GTK_WIDGET(grid));  
172 - return dialog;  
173 - }  
174 -  
175 - static HRESULT CreateShortCut(LPSTR pszTargetfile, LPSTR pszTargetargs, LPSTR pszLinkfile, LPSTR pszDescription, int iShowmode, LPSTR pszCurdir, LPSTR pszIconfile, int iIconindex) {  
176 -  
177 - // https://www.codeproject.com/Articles/11467/How-to-create-short-cuts-link-files  
178 - IShellLink* pShellLink; // IShellLink object pointer  
179 - IPersistFile* pPersistFile; // IPersistFile object pointer  
180 - WORD wszLinkfile[MAX_PATH]; // pszLinkfile as Unicode string  
181 - int iWideCharsWritten; // Number of wide characters written  
182 -  
183 - HRESULT hRes =  
184 - CoCreateInstance(  
185 - &CLSID_ShellLink, // predefined CLSID of the IShellLink object  
186 - NULL, // pointer to parent interface if part of aggregate  
187 - CLSCTX_INPROC_SERVER, // caller and called code are in same process  
188 - &IID_IShellLink, // predefined interface of the IShellLink object  
189 - (void **) &pShellLink); // Returns a pointer to the IShellLink object  
190 -  
191 - if(!SUCCEEDED(hRes)) {  
192 - return hRes;  
193 - }  
194 -  
195 - if(pszTargetfile && strlen(pszTargetfile)) {  
196 - hRes = pShellLink->lpVtbl->SetPath(pShellLink,pszTargetfile);  
197 - } else {  
198 - char filename[MAX_PATH+1];  
199 - memset(filename,0,MAX_PATH+1);  
200 - GetModuleFileName(NULL,filename,MAX_PATH);  
201 - hRes = pShellLink->lpVtbl->SetPath(pShellLink,filename);  
202 - }  
203 -  
204 - if(pszTargetargs) {  
205 - hRes = pShellLink->lpVtbl->SetArguments(pShellLink,pszTargetargs);  
206 - } else {  
207 - hRes = pShellLink->lpVtbl->SetArguments(pShellLink,"");  
208 - }  
209 -  
210 - if(pszDescription && strlen(pszDescription) > 0) {  
211 - hRes = pShellLink->lpVtbl->SetDescription(pShellLink,pszDescription);  
212 - } else {  
213 - hRes = pShellLink->lpVtbl->SetDescription(pShellLink,_("IBM 3270 Terminal emulator"));  
214 - }  
215 -  
216 - if(iShowmode > 0) {  
217 - hRes = pShellLink->lpVtbl->SetShowCmd(pShellLink,iShowmode);  
218 - }  
219 -  
220 - if(pszCurdir && strlen(pszCurdir) > 0) {  
221 - hRes = pShellLink->lpVtbl->SetWorkingDirectory(pShellLink,pszCurdir);  
222 - } else {  
223 - g_autofree gchar * appdir = g_win32_get_package_installation_directory_of_module(NULL);  
224 - hRes = pShellLink->lpVtbl->SetWorkingDirectory(pShellLink,appdir);  
225 - }  
226 -  
227 - if(pszIconfile && strlen(pszIconfile) > 0 && iIconindex >= 0) {  
228 - hRes = pShellLink->lpVtbl->SetIconLocation(pShellLink, pszIconfile, iIconindex);  
229 - }  
230 -  
231 - // Use the IPersistFile object to save the shell link  
232 - hRes = pShellLink->lpVtbl->QueryInterface(  
233 - pShellLink, // existing IShellLink object  
234 - &IID_IPersistFile, // pre-defined interface of the IPersistFile object  
235 - (void **) &pPersistFile); // returns a pointer to the IPersistFile object  
236 -  
237 -  
238 - if(SUCCEEDED(hRes)){  
239 - iWideCharsWritten = MultiByteToWideChar(CP_ACP, 0, pszLinkfile, -1, wszLinkfile, MAX_PATH);  
240 - hRes = pPersistFile->lpVtbl->Save(pPersistFile,wszLinkfile, TRUE);  
241 - pPersistFile->lpVtbl->Release(pPersistFile);  
242 - }  
243 -  
244 - pShellLink->lpVtbl->Release(pShellLink);  
245 -  
246 - return hRes;  
247 - }  
248 -  
249 - void response(GtkWidget *dialog, gint response_id, GtkWidget *terminal) {  
250 -  
251 - debug("%s(%d)",__FUNCTION__,response_id);  
252 -  
253 - if(response_id == GTK_RESPONSE_APPLY) {  
254 -  
255 - // Save desktop icon  
256 - GtkWidget ** inputs = g_object_get_data(G_OBJECT(dialog),"inputs");  
257 -  
258 - HRESULT hRes = CreateShortCut(  
259 - NULL, // LPSTR pszTargetfile,  
260 - v3270_key_file_get_file_name(terminal), // LPSTR pszTargetargs,  
261 - gtk_entry_get_text(GTK_ENTRY(inputs[0])), // LPSTR pszLinkfile,  
262 - gtk_entry_get_text(GTK_ENTRY(inputs[1])), //LPSTR pszDescription,  
263 - 0,  
264 - NULL,  
265 - NULL,  
266 - 0  
267 - );  
268 -  
269 - }  
270 -  
271 - gtk_widget_destroy(dialog);  
272 -  
273 -}