From a7a3d00fa7874fd2dd1c71604ea39c4d8fa9f1cc Mon Sep 17 00:00:00 2001 From: Perry Werneck Date: Thu, 18 Jul 2019 10:33:30 -0300 Subject: [PATCH] Using separated code for linux & windows clipboard interaction. --- src/include/clipboard.h | 1 - src/selection/copy.c | 58 ---------------------------------------------------------- src/selection/linux/copy.c | 150 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/selection/selection.c | 117 --------------------------------------------------------------------------------------------------------------------- src/selection/windows/copy.c | 149 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 299 insertions(+), 176 deletions(-) create mode 100644 src/selection/linux/copy.c create mode 100644 src/selection/windows/copy.c diff --git a/src/include/clipboard.h b/src/include/clipboard.h index 2b9d6e4..1625cba 100644 --- a/src/include/clipboard.h +++ b/src/include/clipboard.h @@ -53,6 +53,5 @@ G_GNUC_INTERNAL gchar * v3270_get_copy_as_text(v3270 * terminal); G_GNUC_INTERNAL gchar * v3270_get_copy_as_table(v3270 * terminal, const gchar *delimiter); - #endif // V3270_CLIPBOARD_H_INCLUDED diff --git a/src/selection/copy.c b/src/selection/copy.c index afef411..d94a1a7 100644 --- a/src/selection/copy.c +++ b/src/selection/copy.c @@ -39,56 +39,6 @@ terminal->selection.blocks = g_list_append(terminal->selection.blocks,selection); } - /* - // Get selection bounds. - unsigned int row; - unsigned int col; - unsigned int width; - unsigned int height; - - if(lib3270_get_selection_rectangle(terminal->host, &row, &col, &width, &height) != 0) - return; - - debug("Selecion rectangle starts on %u,%u with size of %ux%u", - row, col, - width, height - ); - - // Allocate buffer - struct selection * selection = g_malloc0(sizeof(struct selection) + (sizeof(struct v3270_character) * (width * height))); - - selection->bounds.row = row; - selection->bounds.col = col; - selection->bounds.width = width; - selection->bounds.height = height; - - // Copy terminal buffer - unsigned int r, c; - - int pos = 0; - for(r=0;r < selection->bounds.height; r++) - { - // Get starting address. - int baddr = lib3270_translate_to_address(terminal->host, selection->bounds.row+r+1, selection->bounds.col+1); - if(baddr < 0) - { - g_message("Can't convert coordinate %u,%d",selection->bounds.row+r+1,selection->bounds.col+1); - gdk_display_beep(gdk_display_get_default()); - return; - } - - for(c=0;c < selection->bounds.width; c++) - { - lib3270_get_contents(terminal->host,baddr,baddr,&selection->contents[pos].chr,&selection->contents[pos].attr); - debug("pos=%d baddr=%u char=%c",pos,baddr,selection->contents[pos].chr); - pos++; - baddr++; - } - - } - - terminal->selection.blocks = g_list_append(terminal->selection.blocks,selection); - */ } LIB3270_EXPORT void v3270_copy_selection(GtkWidget *widget, V3270_SELECT_FORMAT format, gboolean cut) @@ -105,14 +55,6 @@ v3270_update_system_clipboard(widget); -/* -#ifdef DEBUG - gchar *columns = v3270_get_copy_as_table(terminal,"---"); - debug("Output:\n%s",columns); - g_free(columns); -#endif // DEBUG -*/ - } LIB3270_EXPORT void v3270_append_selection(GtkWidget *widget, gboolean cut) diff --git a/src/selection/linux/copy.c b/src/selection/linux/copy.c new file mode 100644 index 0000000..ddee9b6 --- /dev/null +++ b/src/selection/linux/copy.c @@ -0,0 +1,150 @@ +/* + * "Software pw3270, desenvolvido com base nos códigos fontes do WC3270 e X3270 + * (Paul Mattes Paul.Mattes@usa.net), de emulação de terminal 3270 para acesso a + * aplicativos mainframe. Registro no INPI sob o nome G3270. + * + * Copyright (C) <2008> + * + * Este programa é software livre. Você pode redistribuí-lo e/ou modificá-lo sob + * os termos da GPL v.2 - Licença Pública Geral GNU, conforme publicado pela + * Free Software Foundation. + * + * Este programa é distribuído na expectativa de ser útil, mas SEM QUALQUER + * GARANTIA; sem mesmo a garantia implícita de COMERCIALIZAÇÃO ou de ADEQUAÇÃO + * A QUALQUER PROPÓSITO EM PARTICULAR. Consulte a Licença Pública Geral GNU para + * obter mais detalhes. + * + * Você deve ter recebido uma cópia da Licença Pública Geral GNU junto com este + * programa; se não, escreva para a Free Software Foundation, Inc., 51 Franklin + * St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Este programa está nomeado como - possui - linhas de código. + * + * Contatos: + * + * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck) + * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça) + * + */ + + #include + #include + +/*--[ Implement ]------------------------------------------------------------------------------------*/ + +static void clipboard_clear(G_GNUC_UNUSED GtkClipboard *clipboard, G_GNUC_UNUSED GObject *obj) +{ + v3270 * terminal = GTK_V3270(obj); + + if(!lib3270_get_toggle(terminal->host,LIB3270_TOGGLE_KEEP_SELECTED)) + { + v3270_unselect(GTK_WIDGET(obj)); + v3270_clear_selection(terminal); + } + +} + +static void clipboard_get(G_GNUC_UNUSED GtkClipboard *clipboard, GtkSelectionData *selection, guint target, GObject *obj) +{ + v3270 * terminal = GTK_V3270(obj); + + if(!terminal->selection.blocks) + { + return; + } + + switch(target) + { + case CLIPBOARD_TYPE_TEXT: // Get clipboard contents as text + { + gchar *text; + + if(terminal->selection.format == V3270_SELECT_TABLE) + { + text = v3270_get_copy_as_table(terminal,"\t"); + } + else + { + text = v3270_get_copy_as_text(terminal); + } + gtk_selection_data_set_text(selection,text,-1); + g_free(text); + } + break; + + case CLIPBOARD_TYPE_CSV: + { + g_autofree gchar *text = v3270_get_copy_as_table(terminal,";"); + debug("Selection:\n%s",text); + gtk_selection_data_set( + selection, + gdk_atom_intern_static_string("text/csv"), + 8, + (guchar *) text, + strlen(text) + ); + } + break; + + default: + g_warning("Unexpected clipboard type %d\n",target); + } +} + +void v3270_update_system_clipboard(GtkWidget *widget) +{ + v3270 * terminal = GTK_V3270(widget); + + if(!terminal->selection.blocks) + { + // No clipboard data, return. + g_signal_emit(widget,v3270_widget_signal[V3270_SIGNAL_CLIPBOARD], 0, FALSE); + return; + } + + // Has clipboard data, inform system. + GtkClipboard * clipboard = gtk_widget_get_clipboard(widget,terminal->selection.target); + + // Create target list + // + // Reference: https://cpp.hotexamples.com/examples/-/-/g_list_insert_sorted/cpp-g_list_insert_sorted-function-examples.html + // + static const GtkTargetEntry internal_targets[] = { + { "text/csv", 0, CLIPBOARD_TYPE_CSV } + }; + + GtkTargetList * list = gtk_target_list_new(internal_targets, G_N_ELEMENTS(internal_targets)); + GtkTargetEntry * targets; + int n_targets; + + gtk_target_list_add_text_targets(list, CLIPBOARD_TYPE_TEXT); + + targets = gtk_target_table_new_from_list(list, &n_targets); + +#ifdef DEBUG + { + int ix; + for(ix = 0; ix < n_targets; ix++) { + debug("target(%d)=\"%s\"",ix,targets[ix].target); + } + } +#endif // DEBUG + + if(gtk_clipboard_set_with_owner( + clipboard, + targets, + n_targets, + (GtkClipboardGetFunc) clipboard_get, + (GtkClipboardClearFunc) clipboard_clear, + G_OBJECT(widget) + )) + { + gtk_clipboard_set_can_store(clipboard,targets,1); + } + + gtk_target_table_free(targets, n_targets); + gtk_target_list_unref(list); + + g_signal_emit(widget,v3270_widget_signal[V3270_SIGNAL_CLIPBOARD], 0, TRUE); + +} diff --git a/src/selection/selection.c b/src/selection/selection.c index d28588d..ed90e20 100644 --- a/src/selection/selection.c +++ b/src/selection/selection.c @@ -32,65 +32,6 @@ /*--[ Implement ]------------------------------------------------------------------------------------*/ -static void clipboard_clear(G_GNUC_UNUSED GtkClipboard *clipboard, G_GNUC_UNUSED GObject *obj) -{ - v3270 * terminal = GTK_V3270(obj); - - if(!lib3270_get_toggle(terminal->host,LIB3270_TOGGLE_KEEP_SELECTED)) - { - v3270_unselect(GTK_WIDGET(obj)); - v3270_clear_selection(terminal); - } - -} - -static void clipboard_get(G_GNUC_UNUSED GtkClipboard *clipboard, GtkSelectionData *selection, guint target, GObject *obj) -{ - v3270 * terminal = GTK_V3270(obj); - - if(!terminal->selection.blocks) - { - return; - } - - switch(target) - { - case CLIPBOARD_TYPE_TEXT: // Get clipboard contents as text - { - gchar *text; - - if(terminal->selection.format == V3270_SELECT_TABLE) - { - text = v3270_get_copy_as_table(terminal,"\t"); - } - else - { - text = v3270_get_copy_as_text(terminal); - } - gtk_selection_data_set_text(selection,text,-1); - g_free(text); - } - break; - - case CLIPBOARD_TYPE_CSV: - { - g_autofree gchar *text = v3270_get_copy_as_table(terminal,";"); - debug("Selection:\n%s",text); - gtk_selection_data_set( - selection, - gdk_atom_intern_static_string("text/csv"), - 8, - (guchar *) text, - strlen(text) - ); - } - break; - - default: - g_warning("Unexpected clipboard type %d\n",target); - } -} - /** * Clear clipboard contents. * @@ -131,64 +72,6 @@ LIB3270_EXPORT gchar * v3270_get_selected(GtkWidget *widget, gboolean cut) return NULL; } -void v3270_update_system_clipboard(GtkWidget *widget) -{ - v3270 * terminal = GTK_V3270(widget); - - if(!terminal->selection.blocks) - { - // No clipboard data, return. - g_signal_emit(widget,v3270_widget_signal[V3270_SIGNAL_CLIPBOARD], 0, FALSE); - return; - } - - // Has clipboard data, inform system. - GtkClipboard * clipboard = gtk_widget_get_clipboard(widget,terminal->selection.target); - - // Create target list - // - // Reference: https://cpp.hotexamples.com/examples/-/-/g_list_insert_sorted/cpp-g_list_insert_sorted-function-examples.html - // - static const GtkTargetEntry internal_targets[] = { - { "text/csv", 0, CLIPBOARD_TYPE_CSV } - }; - - GtkTargetList * list = gtk_target_list_new(internal_targets, G_N_ELEMENTS(internal_targets)); - GtkTargetEntry * targets; - int n_targets; - - gtk_target_list_add_text_targets(list, CLIPBOARD_TYPE_TEXT); - - targets = gtk_target_table_new_from_list(list, &n_targets); - -#ifdef DEBUG - { - int ix; - for(ix = 0; ix < n_targets; ix++) { - debug("target(%d)=\"%s\"",ix,targets[ix].target); - } - } -#endif // DEBUG - - if(gtk_clipboard_set_with_owner( - clipboard, - targets, - n_targets, - (GtkClipboardGetFunc) clipboard_get, - (GtkClipboardClearFunc) clipboard_clear, - G_OBJECT(widget) - )) - { - gtk_clipboard_set_can_store(clipboard,targets,1); - } - - gtk_target_table_free(targets, n_targets); - gtk_target_list_unref(list); - - g_signal_emit(widget,v3270_widget_signal[V3270_SIGNAL_CLIPBOARD], 0, TRUE); - -} - LIB3270_EXPORT void v3270_unselect(GtkWidget *widget) { v3270_disable_updates(widget); diff --git a/src/selection/windows/copy.c b/src/selection/windows/copy.c new file mode 100644 index 0000000..69db5a6 --- /dev/null +++ b/src/selection/windows/copy.c @@ -0,0 +1,149 @@ +/* + * "Software pw3270, desenvolvido com base nos códigos fontes do WC3270 e X3270 + * (Paul Mattes Paul.Mattes@usa.net), de emulação de terminal 3270 para acesso a + * aplicativos mainframe. Registro no INPI sob o nome G3270. + * + * Copyright (C) <2008> + * + * Este programa é software livre. Você pode redistribuí-lo e/ou modificá-lo sob + * os termos da GPL v.2 - Licença Pública Geral GNU, conforme publicado pela + * Free Software Foundation. + * + * Este programa é distribuído na expectativa de ser útil, mas SEM QUALQUER + * GARANTIA; sem mesmo a garantia implícita de COMERCIALIZAÇÃO ou de ADEQUAÇÃO + * A QUALQUER PROPÓSITO EM PARTICULAR. Consulte a Licença Pública Geral GNU para + * obter mais detalhes. + * + * Você deve ter recebido uma cópia da Licença Pública Geral GNU junto com este + * programa; se não, escreva para a Free Software Foundation, Inc., 51 Franklin + * St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Este programa está nomeado como - e possui - linhas de código. + * + * Contatos: + * + * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck) + * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça) + * + */ + + #include + #include + +/*--[ Implement ]------------------------------------------------------------------------------------*/ +static void clipboard_clear(G_GNUC_UNUSED GtkClipboard *clipboard, G_GNUC_UNUSED GObject *obj) +{ + v3270 * terminal = GTK_V3270(obj); + + if(!lib3270_get_toggle(terminal->host,LIB3270_TOGGLE_KEEP_SELECTED)) + { + v3270_unselect(GTK_WIDGET(obj)); + v3270_clear_selection(terminal); + } + +} + +static void clipboard_get(G_GNUC_UNUSED GtkClipboard *clipboard, GtkSelectionData *selection, guint target, GObject *obj) +{ + v3270 * terminal = GTK_V3270(obj); + + if(!terminal->selection.blocks) + { + return; + } + + switch(target) + { + case CLIPBOARD_TYPE_TEXT: // Get clipboard contents as text + { + gchar *text; + + if(terminal->selection.format == V3270_SELECT_TABLE) + { + text = v3270_get_copy_as_table(terminal,"\t"); + } + else + { + text = v3270_get_copy_as_text(terminal); + } + gtk_selection_data_set_text(selection,text,-1); + g_free(text); + } + break; + + case CLIPBOARD_TYPE_CSV: + { + g_autofree gchar *text = v3270_get_copy_as_table(terminal,";"); + debug("Selection:\n%s",text); + gtk_selection_data_set( + selection, + gdk_atom_intern_static_string("text/csv"), + 8, + (guchar *) text, + strlen(text) + ); + } + break; + + default: + g_warning("Unexpected clipboard type %d\n",target); + } +} + +void v3270_update_system_clipboard(GtkWidget *widget) +{ + v3270 * terminal = GTK_V3270(widget); + + if(!terminal->selection.blocks) + { + // No clipboard data, return. + g_signal_emit(widget,v3270_widget_signal[V3270_SIGNAL_CLIPBOARD], 0, FALSE); + return; + } + + // Has clipboard data, inform system. + GtkClipboard * clipboard = gtk_widget_get_clipboard(widget,terminal->selection.target); + + // Create target list + // + // Reference: https://cpp.hotexamples.com/examples/-/-/g_list_insert_sorted/cpp-g_list_insert_sorted-function-examples.html + // + static const GtkTargetEntry internal_targets[] = { + { "text/csv", 0, CLIPBOARD_TYPE_CSV } + }; + + GtkTargetList * list = gtk_target_list_new(internal_targets, G_N_ELEMENTS(internal_targets)); + GtkTargetEntry * targets; + int n_targets; + + gtk_target_list_add_text_targets(list, CLIPBOARD_TYPE_TEXT); + + targets = gtk_target_table_new_from_list(list, &n_targets); + +#ifdef DEBUG + { + int ix; + for(ix = 0; ix < n_targets; ix++) { + debug("target(%d)=\"%s\"",ix,targets[ix].target); + } + } +#endif // DEBUG + + if(gtk_clipboard_set_with_owner( + clipboard, + targets, + n_targets, + (GtkClipboardGetFunc) clipboard_get, + (GtkClipboardClearFunc) clipboard_clear, + G_OBJECT(widget) + )) + { + gtk_clipboard_set_can_store(clipboard,targets,1); + } + + gtk_target_table_free(targets, n_targets); + gtk_target_list_unref(list); + + g_signal_emit(widget,v3270_widget_signal[V3270_SIGNAL_CLIPBOARD], 0, TRUE); + +} -- libgit2 0.21.2