Commit eddb289431bef11b13c9d8382eb2c159ee8aa5ba
1 parent
f5e3345e
Exists in
master
and in
1 other branch
Adding simple trace window.
Showing
1 changed file
with
485 additions
and
0 deletions
Show diff stats
@@ -0,0 +1,485 @@ | @@ -0,0 +1,485 @@ | ||
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 trace.c 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 <gtk/gtk.h> | ||
31 | + | ||
32 | + #define ENABLE_NLS | ||
33 | + #define GETTEXT_PACKAGE PACKAGE_NAME | ||
34 | + | ||
35 | + #include <libintl.h> | ||
36 | + #include <glib/gi18n.h> | ||
37 | + | ||
38 | + #include <v3270/trace.h> | ||
39 | + | ||
40 | +#if defined( HAVE_SYSLOG ) | ||
41 | + #include <syslog.h> | ||
42 | +#endif // HAVE_SYSLOG | ||
43 | + | ||
44 | +/*--[ Widget definition ]----------------------------------------------------------------------------*/ | ||
45 | + | ||
46 | + G_BEGIN_DECLS | ||
47 | + | ||
48 | + struct _v3270_traceClass | ||
49 | + { | ||
50 | + GtkWindowClass parent_class; | ||
51 | + }; | ||
52 | + | ||
53 | + struct _v3270_trace | ||
54 | + { | ||
55 | + GtkWindow parent; | ||
56 | + GtkAdjustment * scroll; | ||
57 | + GtkTextBuffer * text; | ||
58 | + GtkWidget * entry; | ||
59 | + GtkWidget * button; | ||
60 | + gchar **line; | ||
61 | + guint log_handler; | ||
62 | + gboolean * enabled; | ||
63 | + gboolean destroy_on_close; | ||
64 | + }; | ||
65 | + | ||
66 | + const GtkWindowClass * v3270_trace_get_parent_class(void); | ||
67 | + | ||
68 | + G_END_DECLS | ||
69 | + | ||
70 | + G_DEFINE_TYPE(v3270_trace, v3270_trace, GTK_TYPE_WINDOW); | ||
71 | + | ||
72 | +/*--[ Implement ]------------------------------------------------------------------------------------*/ | ||
73 | + | ||
74 | + const GtkWindowClass * v3270_trace_get_parent_class(void) | ||
75 | + { | ||
76 | + return GTK_WINDOW_CLASS(v3270_trace_parent_class); | ||
77 | + } | ||
78 | + | ||
79 | + static void activate_default(GtkWindow *window) | ||
80 | + { | ||
81 | + v3270_trace * hwnd = V3270_TRACE(window); | ||
82 | + | ||
83 | + if(hwnd->enabled) | ||
84 | + { | ||
85 | + if(*hwnd->line) | ||
86 | + g_free(*hwnd->line); | ||
87 | + | ||
88 | + *hwnd->line = g_strdup(gtk_entry_get_text(GTK_ENTRY(hwnd->entry))); | ||
89 | + | ||
90 | + gtk_widget_set_sensitive(hwnd->entry,FALSE); | ||
91 | + gtk_widget_set_sensitive(hwnd->button,FALSE); | ||
92 | + | ||
93 | + *hwnd->enabled = FALSE; | ||
94 | + } | ||
95 | + | ||
96 | + } | ||
97 | + | ||
98 | +#if GTK_CHECK_VERSION(3,0,0) | ||
99 | +static void destroy(GtkWidget *widget) | ||
100 | +#else | ||
101 | +static void destroy(GtkObject *widget) | ||
102 | +#endif | ||
103 | + { | ||
104 | + v3270_trace * hwnd = V3270_TRACE(widget); | ||
105 | + | ||
106 | + if(hwnd->log_handler) | ||
107 | + { | ||
108 | + g_log_remove_handler(NULL,hwnd->log_handler); | ||
109 | + hwnd->log_handler = 0; | ||
110 | + } | ||
111 | + | ||
112 | + if(hwnd->line) | ||
113 | + *hwnd->line = NULL; | ||
114 | + | ||
115 | + if(hwnd->enabled) | ||
116 | + *hwnd->enabled = FALSE; | ||
117 | + | ||
118 | + } | ||
119 | + | ||
120 | + static gboolean delete_event(GtkWidget *widget, G_GNUC_UNUSED GdkEventAny *event) | ||
121 | + { | ||
122 | + v3270_trace * hwnd = V3270_TRACE(widget); | ||
123 | + | ||
124 | + if(hwnd->line) | ||
125 | + *hwnd->line = NULL; | ||
126 | + | ||
127 | + if(hwnd->enabled) | ||
128 | + *hwnd->enabled = FALSE; | ||
129 | + | ||
130 | + if(hwnd->destroy_on_close) | ||
131 | + return FALSE; | ||
132 | + | ||
133 | + gtk_widget_hide(widget); | ||
134 | + return TRUE; | ||
135 | + } | ||
136 | + | ||
137 | + static void v3270_trace_class_init(v3270_traceClass *klass) | ||
138 | + { | ||
139 | + GtkWindowClass * window_class = GTK_WINDOW_CLASS(klass); | ||
140 | + GtkWidgetClass * widget_class = GTK_WIDGET_CLASS(klass); | ||
141 | + | ||
142 | + window_class->activate_default = activate_default; | ||
143 | + widget_class->delete_event = delete_event; | ||
144 | + | ||
145 | +#if GTK_CHECK_VERSION(3,0,0) | ||
146 | + { | ||
147 | + widget_class->destroy = destroy; | ||
148 | + } | ||
149 | +#else | ||
150 | + { | ||
151 | + GtkObjectClass *object_class = (GtkObjectClass*) klass; | ||
152 | + object_class->destroy = destroy; | ||
153 | + } | ||
154 | +#endif // GTK3 | ||
155 | + | ||
156 | + } | ||
157 | + | ||
158 | + static void activate(G_GNUC_UNUSED GtkButton *button, GtkWindow *window) | ||
159 | + { | ||
160 | + activate_default(window); | ||
161 | + } | ||
162 | + | ||
163 | + static void menu_save(G_GNUC_UNUSED GtkWidget *button, v3270_trace *window) | ||
164 | + { | ||
165 | + GtkWindow * toplevel = GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(window))); | ||
166 | + GtkWidget * dialog; | ||
167 | + | ||
168 | + dialog = gtk_file_chooser_dialog_new( _( "Save trace file" ), | ||
169 | + toplevel, | ||
170 | + GTK_FILE_CHOOSER_ACTION_SAVE, | ||
171 | + GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, | ||
172 | + GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT, | ||
173 | + NULL ); | ||
174 | + | ||
175 | + gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(dialog), TRUE); | ||
176 | + | ||
177 | + gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog),g_get_user_special_dir(G_USER_DIRECTORY_DOCUMENTS)); | ||
178 | + | ||
179 | + if(gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) | ||
180 | + { | ||
181 | + gchar *filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); | ||
182 | + if(filename) | ||
183 | + { | ||
184 | + GError * error = NULL; | ||
185 | + gchar * text; | ||
186 | + GtkTextIter start; | ||
187 | + GtkTextIter end; | ||
188 | + | ||
189 | + gtk_text_buffer_get_start_iter(window->text,&start); | ||
190 | + gtk_text_buffer_get_end_iter(window->text,&end); | ||
191 | + text = gtk_text_buffer_get_text(window->text,&start,&end,FALSE); | ||
192 | + | ||
193 | + g_file_set_contents(filename,text,-1,&error); | ||
194 | + | ||
195 | + g_free(text); | ||
196 | + | ||
197 | + if(error) | ||
198 | + { | ||
199 | + GtkWidget *popup = gtk_message_dialog_new_with_markup(GTK_WINDOW(dialog),GTK_DIALOG_MODAL|GTK_DIALOG_DESTROY_WITH_PARENT,GTK_MESSAGE_ERROR,GTK_BUTTONS_CLOSE,_( "Can't save %s" ),filename); | ||
200 | + | ||
201 | + gtk_window_set_title(GTK_WINDOW(popup),_("Can't save file")); | ||
202 | + | ||
203 | + gtk_message_dialog_format_secondary_markup(GTK_MESSAGE_DIALOG(popup),"%s",error->message); | ||
204 | + g_error_free(error); | ||
205 | + | ||
206 | + gtk_dialog_run(GTK_DIALOG(popup)); | ||
207 | + gtk_widget_destroy(popup); | ||
208 | + | ||
209 | + } | ||
210 | + | ||
211 | + g_free(filename); | ||
212 | + } | ||
213 | + } | ||
214 | + | ||
215 | + gtk_widget_destroy(dialog); | ||
216 | + | ||
217 | + } | ||
218 | + | ||
219 | + static void menu_close(G_GNUC_UNUSED GtkWidget *button, GtkWidget *window) | ||
220 | + { | ||
221 | + gtk_widget_destroy(window); | ||
222 | + } | ||
223 | + | ||
224 | + struct submenu | ||
225 | + { | ||
226 | + const gchar * stock_id; | ||
227 | + GCallback action; | ||
228 | + }; | ||
229 | + | ||
230 | + static void build_menu(GtkWidget *menubar, v3270_trace *window, const gchar *name, const struct submenu *item, size_t sz) | ||
231 | + { | ||
232 | + size_t f; | ||
233 | + GtkWidget * menu = gtk_menu_new(); | ||
234 | + GtkWidget * topitem = gtk_image_menu_item_new_from_stock( name, NULL ); | ||
235 | + | ||
236 | + gtk_menu_item_set_submenu(GTK_MENU_ITEM(topitem), menu); | ||
237 | + | ||
238 | + for(f=0;f<sz;f++) | ||
239 | + { | ||
240 | + GtkWidget *widget = gtk_image_menu_item_new_from_stock( item[f].stock_id, NULL ); | ||
241 | + gtk_menu_shell_append(GTK_MENU_SHELL(menu),widget); | ||
242 | + g_signal_connect(G_OBJECT(widget), "activate",item[f].action,window); | ||
243 | + } | ||
244 | + | ||
245 | + gtk_menu_shell_append(GTK_MENU_SHELL(menubar), topitem); | ||
246 | + } | ||
247 | + | ||
248 | + static void glog(const gchar *log_domain,GLogLevelFlags log_level,const gchar *message,GtkWidget *window) | ||
249 | + { | ||
250 | + #ifndef LOG_INFO | ||
251 | + #define LOG_INFO 0 | ||
252 | + #endif // LOG_INFO | ||
253 | + | ||
254 | + #ifndef LOG_ERR | ||
255 | + #define LOG_ERR 0 | ||
256 | + #endif // LOG_ERR | ||
257 | + | ||
258 | + #ifndef LOG_DEBUG | ||
259 | + #define LOG_DEBUG 0 | ||
260 | + #endif // LOG_DEBUG | ||
261 | + | ||
262 | + static const struct _logtype | ||
263 | + { | ||
264 | + GLogLevelFlags log_level; | ||
265 | + int priority; | ||
266 | + const gchar * msg; | ||
267 | + } logtype[] = | ||
268 | + { | ||
269 | + { G_LOG_FLAG_RECURSION, LOG_INFO, "recursion" }, | ||
270 | + { G_LOG_FLAG_FATAL, LOG_ERR, "fatal error" }, | ||
271 | + | ||
272 | + /* GLib log levels */ | ||
273 | + { G_LOG_LEVEL_ERROR, LOG_ERR, "error" }, | ||
274 | + { G_LOG_LEVEL_CRITICAL, LOG_ERR, "critical error" }, | ||
275 | + { G_LOG_LEVEL_WARNING, LOG_ERR, "warning" }, | ||
276 | + { G_LOG_LEVEL_MESSAGE, LOG_ERR, "message" }, | ||
277 | + { G_LOG_LEVEL_INFO, LOG_INFO, "info" }, | ||
278 | + { G_LOG_LEVEL_DEBUG, LOG_DEBUG, "debug" }, | ||
279 | + }; | ||
280 | + | ||
281 | + size_t f; | ||
282 | + | ||
283 | + for(f=0;f<G_N_ELEMENTS(logtype);f++) | ||
284 | + { | ||
285 | + if(logtype[f].log_level == log_level) | ||
286 | + { | ||
287 | + gchar *ptr; | ||
288 | + gchar *text = g_strdup_printf("%s: %s %s",logtype[f].msg,log_domain ? log_domain : "",message); | ||
289 | + for(ptr = text;*ptr;ptr++) | ||
290 | + { | ||
291 | + if(*ptr < ' ') | ||
292 | + *ptr = ' '; | ||
293 | + } | ||
294 | + | ||
295 | + v3270_trace_printf(window,"%s\n",text); | ||
296 | + | ||
297 | +#ifdef HAVE_SYSLOG | ||
298 | + syslog(logtype[f].priority,"%s",text); | ||
299 | +#endif // HAVE_SYSLOG | ||
300 | + g_free(text); | ||
301 | + return; | ||
302 | + } | ||
303 | + } | ||
304 | + | ||
305 | + v3270_trace_printf(window,"%s %s\n",log_domain ? log_domain : "", message); | ||
306 | + | ||
307 | +#ifdef HAVE_SYSLOG | ||
308 | + syslog(LOG_INFO,"%s %s",log_domain ? log_domain : "", message); | ||
309 | +#endif // HAVE_SYSLOG | ||
310 | + | ||
311 | + } | ||
312 | + | ||
313 | + static void v3270_trace_init(v3270_trace *window) | ||
314 | + { | ||
315 | + GtkWidget * widget; | ||
316 | + GtkWidget * view; | ||
317 | +#if GTK_CHECK_VERSION(3,0,0) | ||
318 | + GtkWidget * vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL,0); | ||
319 | +#else | ||
320 | + GtkWidget * vbox = gtk_vbox_new(FALSE,0); | ||
321 | +#endif // GTK_CHECK_VERSION | ||
322 | + gchar * fontname = "Monospace"; | ||
323 | + PangoFontDescription * fontdesc = pango_font_description_from_string(fontname); | ||
324 | + | ||
325 | + g_free(fontname); | ||
326 | + | ||
327 | + // Top menu | ||
328 | + { | ||
329 | + | ||
330 | + static const struct submenu filemenu[] = | ||
331 | + { | ||
332 | + { GTK_STOCK_SAVE_AS, G_CALLBACK(menu_save) }, | ||
333 | + { GTK_STOCK_QUIT, G_CALLBACK(menu_close) }, | ||
334 | + | ||
335 | + }; | ||
336 | + | ||
337 | + widget = gtk_menu_bar_new(); | ||
338 | + | ||
339 | + build_menu(widget, window, GTK_STOCK_FILE, filemenu, G_N_ELEMENTS(filemenu)); | ||
340 | + | ||
341 | + gtk_box_pack_start(GTK_BOX(vbox),widget,FALSE,TRUE,0); | ||
342 | + } | ||
343 | + | ||
344 | + // Trace container | ||
345 | + widget = gtk_scrolled_window_new(NULL,NULL); | ||
346 | + window->scroll = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(widget)); | ||
347 | + gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(widget),GTK_POLICY_AUTOMATIC,GTK_POLICY_AUTOMATIC); | ||
348 | + view = gtk_text_view_new(); | ||
349 | + | ||
350 | +#if GTK_CHECK_VERSION(3,0,0) | ||
351 | + gtk_widget_override_font(GTK_WIDGET(view), fontdesc); | ||
352 | +#else | ||
353 | + gtk_widget_modify_font(GTK_WIDGET(view), fontdesc); | ||
354 | +#endif // GTK_CHECK_VERSION | ||
355 | + | ||
356 | + window->text = gtk_text_view_get_buffer(GTK_TEXT_VIEW(view)); | ||
357 | + gtk_text_view_set_editable(GTK_TEXT_VIEW(view), TRUE); | ||
358 | + | ||
359 | +#if GTK_CHECK_VERSION(3,8,0) | ||
360 | + gtk_container_add(GTK_CONTAINER(widget),view); | ||
361 | +#else | ||
362 | + gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(widget),view); | ||
363 | +#endif // GTK_CHECK_VERSION | ||
364 | + gtk_box_pack_start(GTK_BOX(vbox),widget,TRUE,TRUE,0); | ||
365 | + | ||
366 | + // Edit box | ||
367 | +#if GTK_CHECK_VERSION(3,0,0) | ||
368 | + widget = gtk_box_new(GTK_ORIENTATION_HORIZONTAL,0); | ||
369 | +#else | ||
370 | + widget = gtk_hbox_new(FALSE,0); | ||
371 | +#endif // GTK_CHECK_VERSION | ||
372 | + gtk_box_pack_start(GTK_BOX(widget),gtk_label_new( _( "Command:" )),FALSE,TRUE,4); | ||
373 | + window->entry = gtk_entry_new(); | ||
374 | + gtk_box_pack_start(GTK_BOX(widget),window->entry,TRUE,TRUE,4); | ||
375 | + gtk_widget_set_sensitive(window->entry,FALSE); | ||
376 | + g_signal_connect(G_OBJECT(window->entry),"activate",G_CALLBACK(activate),window); | ||
377 | + | ||
378 | + window->button = gtk_button_new_from_stock(GTK_STOCK_OK); | ||
379 | + gtk_box_pack_end(GTK_BOX(widget),window->button,FALSE,FALSE,4); | ||
380 | + gtk_widget_set_sensitive(window->button,FALSE); | ||
381 | + gtk_widget_set_focus_on_click(GTK_BUTTON(window->button),FALSE); | ||
382 | + | ||
383 | + g_signal_connect(G_OBJECT(window->button),"clicked",G_CALLBACK(activate),window); | ||
384 | + | ||
385 | + gtk_box_pack_start(GTK_BOX(vbox),widget,FALSE,TRUE,0); | ||
386 | + | ||
387 | + gtk_widget_show_all(vbox); | ||
388 | + | ||
389 | + gtk_container_add(GTK_CONTAINER(window),vbox); | ||
390 | + | ||
391 | + pango_font_description_free(fontdesc); | ||
392 | + | ||
393 | + window->log_handler = g_log_set_handler(NULL,G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION,(GLogFunc) glog,window); | ||
394 | + | ||
395 | + } | ||
396 | + | ||
397 | + GtkWidget * v3270_trace_new(H3270 *hSession) | ||
398 | + { | ||
399 | + return g_object_new(V3270_TYPE_TRACE, NULL); | ||
400 | + } | ||
401 | + | ||
402 | + LIB3270_EXPORT GtkWidget * v3270_trace_new_from_session(H3270 *hSession) { | ||
403 | + GtkWidget * widget = g_object_new(V3270_TYPE_TRACE, NULL); | ||
404 | + void * terminal = lib3270_get_user_data(hSession); | ||
405 | + | ||
406 | + gtk_window_set_default_size(GTK_WINDOW(widget),590,430); | ||
407 | + | ||
408 | + if(terminal && GTK_IS_V3270(terminal)) | ||
409 | + { | ||
410 | + GtkWidget * toplevel = gtk_widget_get_toplevel(GTK_WIDGET(terminal)); | ||
411 | + gtk_window_set_attached_to(GTK_WINDOW(widget),toplevel); | ||
412 | + | ||
413 | + } | ||
414 | + | ||
415 | + return widget; | ||
416 | + } | ||
417 | + | ||
418 | + | ||
419 | + void v3270_trace_vprintf(GtkWidget *widget, const char *fmt, va_list args) | ||
420 | + { | ||
421 | + GtkTextIter itr; | ||
422 | + gchar * msg; | ||
423 | + v3270_trace * hwnd = V3270_TRACE(widget); | ||
424 | + | ||
425 | + gtk_text_buffer_get_end_iter(hwnd->text,&itr); | ||
426 | + | ||
427 | + msg = g_strdup_vprintf(fmt,args); | ||
428 | + | ||
429 | + if(g_utf8_validate(msg,strlen(msg),NULL)) | ||
430 | + { | ||
431 | + gtk_text_buffer_insert(hwnd->text,&itr,msg,strlen(msg)); | ||
432 | + } | ||
433 | + else | ||
434 | + { | ||
435 | + gtk_text_buffer_insert(hwnd->text,&itr,"** Invalid UTF8 String **",-1); | ||
436 | + } | ||
437 | + g_free(msg); | ||
438 | + | ||
439 | + gtk_text_buffer_get_end_iter(hwnd->text,&itr); | ||
440 | + | ||
441 | +#if GTK_CHECK_VERSION(2,14,0) | ||
442 | + gtk_adjustment_set_value(hwnd->scroll,gtk_adjustment_get_upper(hwnd->scroll)); | ||
443 | +#else | ||
444 | + gtk_adjustment_set_value(hwnd->scroll,(GTK_ADJUSTMENT(hwnd->scroll))->upper); | ||
445 | +#endif // | ||
446 | + | ||
447 | + } | ||
448 | + | ||
449 | + void v3270_trace_printf(GtkWidget *widget, const char *fmt, ... ) | ||
450 | + { | ||
451 | + va_list arg_ptr; | ||
452 | + va_start(arg_ptr, fmt); | ||
453 | + v3270_trace_vprintf(widget,fmt,arg_ptr); | ||
454 | + va_end(arg_ptr); | ||
455 | + } | ||
456 | + | ||
457 | + LIB3270_EXPORT gchar * v3270_trace_get_command(GtkWidget *widget) | ||
458 | + { | ||
459 | + v3270_trace * hwnd = V3270_TRACE(widget); | ||
460 | + gchar * line = NULL; | ||
461 | + gboolean enabled = TRUE; | ||
462 | + | ||
463 | + hwnd->line = &line; | ||
464 | + hwnd->enabled = &enabled; | ||
465 | + | ||
466 | + gtk_window_present(GTK_WINDOW(widget)); | ||
467 | + gtk_widget_set_sensitive(hwnd->entry,TRUE); | ||
468 | + gtk_widget_set_sensitive(hwnd->button,TRUE); | ||
469 | + gtk_widget_grab_focus(hwnd->entry); | ||
470 | + | ||
471 | + while(enabled) | ||
472 | + { | ||
473 | + gtk_main_iteration(); | ||
474 | + } | ||
475 | + | ||
476 | + hwnd->line = NULL; | ||
477 | + hwnd->enabled = NULL; | ||
478 | + | ||
479 | + return line; | ||
480 | + } | ||
481 | + | ||
482 | + LIB3270_EXPORT void v3270_trace_set_destroy_on_close(GtkWidget *widget,gboolean on) | ||
483 | + { | ||
484 | + V3270_TRACE(widget)->destroy_on_close = on; | ||
485 | + } |