Commit 5084f86c04e050eaaa0a20fffc1718d38670dd2f

Authored by Perry Werneck
1 parent a04b1cb7
Exists in master and in 1 other branch develop

Improving clipboard management.

Makefile.in
... ... @@ -33,8 +33,8 @@ SOURCES= \
33 33 $(wildcard src/terminal/@OSNAME@/*.rc) \
34 34 $(wildcard src/terminal/@OSNAME@/*.c) \
35 35 $(wildcard src/filetransfer/*.c) \
36   - $(wildcard src/clipboard/*.c) \
37   - $(wildcard src/clipboard/@OSNAME@/*.c) \
  36 + $(wildcard src/selection/*.c) \
  37 + $(wildcard src/selection/@OSNAME@/*.c) \
38 38 $(wildcard src/trace/*.c) \
39 39 $(wildcard src/dialogs/*.c) \
40 40 $(wildcard src/dialogs/@OSNAME@/*.c) \
... ...
src/clipboard/copy.c
... ... @@ -1,129 +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   - #include <clipboard.h>
31   - #include <lib3270/selection.h>
32   -
33   - static void do_copy(v3270 *terminal, gboolean cut)
34   - {
35   - lib3270_selection * selection = lib3270_get_selection(terminal->host,cut);
36   -
37   - if(selection)
38   - {
39   - terminal->selection.blocks = g_list_append(terminal->selection.blocks,selection);
40   - }
41   -
42   - /*
43   - // Get selection bounds.
44   - unsigned int row;
45   - unsigned int col;
46   - unsigned int width;
47   - unsigned int height;
48   -
49   - if(lib3270_get_selection_rectangle(terminal->host, &row, &col, &width, &height) != 0)
50   - return;
51   -
52   - debug("Selecion rectangle starts on %u,%u with size of %ux%u",
53   - row, col,
54   - width, height
55   - );
56   -
57   - // Allocate buffer
58   - struct selection * selection = g_malloc0(sizeof(struct selection) + (sizeof(struct v3270_character) * (width * height)));
59   -
60   - selection->bounds.row = row;
61   - selection->bounds.col = col;
62   - selection->bounds.width = width;
63   - selection->bounds.height = height;
64   -
65   - // Copy terminal buffer
66   - unsigned int r, c;
67   -
68   - int pos = 0;
69   - for(r=0;r < selection->bounds.height; r++)
70   - {
71   - // Get starting address.
72   - int baddr = lib3270_translate_to_address(terminal->host, selection->bounds.row+r+1, selection->bounds.col+1);
73   - if(baddr < 0)
74   - {
75   - g_message("Can't convert coordinate %u,%d",selection->bounds.row+r+1,selection->bounds.col+1);
76   - gdk_display_beep(gdk_display_get_default());
77   - return;
78   - }
79   -
80   - for(c=0;c < selection->bounds.width; c++)
81   - {
82   - lib3270_get_contents(terminal->host,baddr,baddr,&selection->contents[pos].chr,&selection->contents[pos].attr);
83   - debug("pos=%d baddr=%u char=%c",pos,baddr,selection->contents[pos].chr);
84   - pos++;
85   - baddr++;
86   - }
87   -
88   - }
89   -
90   - terminal->selection.blocks = g_list_append(terminal->selection.blocks,selection);
91   - */
92   - }
93   -
94   - LIB3270_EXPORT void v3270_copy_selection(GtkWidget *widget, V3270_SELECT_FORMAT format, gboolean cut)
95   - {
96   - g_return_if_fail(GTK_IS_V3270(widget));
97   -
98   - v3270 * terminal = GTK_V3270(widget);
99   -
100   - // Have data? Clear it?
101   - v3270_clear_selection(terminal);
102   -
103   - terminal->selection.format = format;
104   - do_copy(terminal,cut);
105   -
106   - v3270_update_system_clipboard(widget);
107   -
108   -/*
109   -#ifdef DEBUG
110   - gchar *columns = v3270_get_copy_as_table(terminal,"---");
111   - debug("Output:\n%s",columns);
112   - g_free(columns);
113   -#endif // DEBUG
114   -*/
115   -
116   - }
117   -
118   - LIB3270_EXPORT void v3270_append_selection(GtkWidget *widget, gboolean cut)
119   - {
120   - g_return_if_fail(GTK_IS_V3270(widget));
121   -
122   - v3270 * terminal = GTK_V3270(widget);
123   -
124   - do_copy(terminal,cut);
125   -
126   - v3270_update_system_clipboard(widget);
127   -
128   - }
129   -
src/clipboard/linux/paste.c
... ... @@ -1,43 +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 selection.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 <clipboard.h>
31   -
32   -/*--[ Implement ]------------------------------------------------------------------------------------*/
33   -
34   -static void text_received(G_GNUC_UNUSED GtkClipboard *clipboard, const gchar *text, GtkWidget *widget)
35   -{
36   - v3270_paste_text(widget,text,"UTF-8");
37   -}
38   -
39   -LIB3270_EXPORT void v3270_paste(GtkWidget *widget)
40   -{
41   - gtk_clipboard_request_text(gtk_widget_get_clipboard(widget,GDK_SELECTION_CLIPBOARD),(GtkClipboardTextReceivedFunc) text_received,(gpointer) widget);
42   -}
43   -
src/clipboard/selection.c
... ... @@ -1,219 +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 selection.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 <clipboard.h>
31   - #include <lib3270/selection.h>
32   -
33   -/*--[ Implement ]------------------------------------------------------------------------------------*/
34   -
35   -static void clipboard_clear(G_GNUC_UNUSED GtkClipboard *clipboard, G_GNUC_UNUSED GObject *obj)
36   -{
37   - v3270 * terminal = GTK_V3270(obj);
38   -
39   - if(!lib3270_get_toggle(terminal->host,LIB3270_TOGGLE_KEEP_SELECTED))
40   - {
41   - v3270_unselect(GTK_WIDGET(obj));
42   - v3270_clear_selection(terminal);
43   - }
44   -
45   -}
46   -
47   -static void clipboard_get(G_GNUC_UNUSED GtkClipboard *clipboard, GtkSelectionData *selection, guint target, GObject *obj)
48   -{
49   - v3270 * terminal = GTK_V3270(obj);
50   -
51   - if(!terminal->selection.blocks)
52   - {
53   - return;
54   - }
55   -
56   - switch(target)
57   - {
58   - case CLIPBOARD_TYPE_TEXT: // Get clipboard contents as text
59   - {
60   - gchar *text;
61   -
62   - if(terminal->selection.format == V3270_SELECT_TABLE)
63   - {
64   - text = v3270_get_copy_as_table(terminal,"\t");
65   - }
66   - else
67   - {
68   - text = v3270_get_copy_as_text(terminal);
69   - }
70   - gtk_selection_data_set_text(selection,text,-1);
71   - g_free(text);
72   - }
73   - break;
74   -
75   - case CLIPBOARD_TYPE_CSV:
76   - {
77   - g_autofree gchar *text = v3270_get_copy_as_table(terminal,";");
78   - debug("Selection:\n%s",text);
79   - gtk_selection_data_set(
80   - selection,
81   - gdk_atom_intern_static_string("text/csv"),
82   - 8,
83   - (guchar *) text,
84   - strlen(text)
85   - );
86   - }
87   - break;
88   -
89   - default:
90   - g_warning("Unexpected clipboard type %d\n",target);
91   - }
92   -}
93   -
94   -/**
95   - * Clear clipboard contents.
96   - *
97   - * @param terminal Pointer to the terminal Widget.
98   - *
99   - */
100   -void v3270_clear_selection(v3270 *terminal)
101   -{
102   - if(terminal->selection.blocks)
103   - {
104   - g_list_free_full(terminal->selection.blocks,(GDestroyNotify) lib3270_free);
105   - terminal->selection.blocks = NULL;
106   - }
107   -}
108   -
109   -/**
110   - * Get lib3270 selection as a g_malloc buffer.
111   - *
112   - * @param widget Widget containing the desired section.
113   - *
114   - * @return NULL if error, otherwise the selected buffer contents (release with g_free).
115   - *
116   - */
117   -LIB3270_EXPORT gchar * v3270_get_selected(GtkWidget *widget, gboolean cut)
118   -{
119   - lib3270_autoptr(char) text = NULL;
120   -
121   - g_return_val_if_fail(GTK_IS_V3270(widget),NULL);
122   -
123   - if(cut)
124   - text = lib3270_cut_selected(GTK_V3270(widget)->host);
125   - else
126   - text = lib3270_get_selected(GTK_V3270(widget)->host);
127   -
128   - if(text)
129   - return g_convert(text, -1, "UTF-8", lib3270_get_display_charset(GTK_V3270(widget)->host), NULL, NULL, NULL);
130   -
131   - return NULL;
132   -}
133   -
134   -void v3270_update_system_clipboard(GtkWidget *widget)
135   -{
136   - v3270 * terminal = GTK_V3270(widget);
137   -
138   - if(!terminal->selection.blocks)
139   - {
140   - // No clipboard data, return.
141   - g_signal_emit(widget,v3270_widget_signal[V3270_SIGNAL_CLIPBOARD], 0, FALSE);
142   - return;
143   - }
144   -
145   - // Has clipboard data, inform system.
146   - GtkClipboard * clipboard = gtk_widget_get_clipboard(widget,terminal->selection.target);
147   -
148   - // Create target list
149   - //
150   - // Reference: https://cpp.hotexamples.com/examples/-/-/g_list_insert_sorted/cpp-g_list_insert_sorted-function-examples.html
151   - //
152   - static const GtkTargetEntry internal_targets[] = {
153   - { "text/csv", 0, CLIPBOARD_TYPE_CSV }
154   - };
155   -
156   - GtkTargetList * list = gtk_target_list_new(internal_targets, G_N_ELEMENTS(internal_targets));
157   - GtkTargetEntry * targets;
158   - int n_targets;
159   -
160   - gtk_target_list_add_text_targets(list, CLIPBOARD_TYPE_TEXT);
161   -
162   - targets = gtk_target_table_new_from_list(list, &n_targets);
163   -
164   -#ifdef DEBUG
165   - {
166   - int ix;
167   - for(ix = 0; ix < n_targets; ix++) {
168   - debug("target(%d)=\"%s\"",ix,targets[ix].target);
169   - }
170   - }
171   -#endif // DEBUG
172   -
173   - if(gtk_clipboard_set_with_owner(
174   - clipboard,
175   - targets,
176   - n_targets,
177   - (GtkClipboardGetFunc) clipboard_get,
178   - (GtkClipboardClearFunc) clipboard_clear,
179   - G_OBJECT(widget)
180   - ))
181   - {
182   - gtk_clipboard_set_can_store(clipboard,targets,1);
183   - }
184   -
185   - gtk_target_table_free(targets, n_targets);
186   - gtk_target_list_unref(list);
187   -
188   - g_signal_emit(widget,v3270_widget_signal[V3270_SIGNAL_CLIPBOARD], 0, TRUE);
189   -
190   -}
191   -
192   -LIB3270_EXPORT void v3270_unselect(GtkWidget *widget)
193   -{
194   - v3270_disable_updates(widget);
195   - lib3270_unselect(v3270_get_session(widget));
196   - v3270_enable_updates(widget);
197   -}
198   -
199   -gboolean v3270_get_selection_bounds(GtkWidget *widget, gint *start, gint *end)
200   -{
201   - g_return_val_if_fail(GTK_IS_V3270(widget),FALSE);
202   - return lib3270_get_selection_bounds(GTK_V3270(widget)->host,start,end) == 0 ? FALSE : TRUE;
203   -}
204   -
205   -LIB3270_EXPORT void v3270_select_region(GtkWidget *widget, gint start, gint end)
206   -{
207   - g_return_if_fail(GTK_IS_V3270(widget));
208   - lib3270_select_region(GTK_V3270(widget)->host,start,end);
209   -}
210   -
211   -LIB3270_EXPORT void v3270_select_all(GtkWidget *widget)
212   -{
213   - g_return_if_fail(GTK_IS_V3270(widget));
214   - v3270_disable_updates(widget);
215   - lib3270_select_all(v3270_get_session(widget));
216   - v3270_enable_updates(widget);
217   -}
218   -
219   -
src/clipboard/table.c
... ... @@ -1,176 +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   - #include <clipboard.h>
31   - #include <ctype.h>
32   - #include <lib3270/selection.h>
33   -
34   - struct ColumnDescription {
35   - unsigned int begin;
36   - unsigned int width;
37   - };
38   -
39   -/*--[ Implement ]------------------------------------------------------------------------------------*/
40   -
41   -/// @brief Check if column has data.
42   -static gboolean hasDataOnColumn(v3270 * terminal, unsigned int col)
43   -{
44   - GList * element = terminal->selection.blocks;
45   -
46   - while(element)
47   - {
48   - lib3270_selection * block = ((lib3270_selection *) element->data);
49   -
50   - if( (col >= block->bounds.col) && ( col < (block->bounds.col + block->bounds.width)) )
51   - {
52   - unsigned int pos = col-block->bounds.col;
53   - unsigned int row;
54   -
55   - for(row = 0; row < block->bounds.height; row++)
56   - {
57   - if( (block->contents[pos].flags & LIB3270_ATTR_SELECTED) && !isspace(block->contents[pos].chr))
58   - {
59   - return TRUE;
60   - }
61   - pos += block->bounds.width;
62   - }
63   -
64   - }
65   -
66   - element = g_list_next(element);
67   - }
68   -
69   - return FALSE;
70   -}
71   -
72   -/// @brief Get column list.
73   -GList * getColumns(v3270 * terminal)
74   -{
75   - unsigned int col = 0;
76   - GList *rc = NULL;
77   -
78   - while(col < lib3270_get_width(terminal->host)) {
79   -
80   - // debug("col(%u): %s", col, hasDataOnColumn(terminal,col) ? "yes" : "no");
81   -
82   - // Get first column.
83   - while(!hasDataOnColumn(terminal,col)) {
84   - if(col >= lib3270_get_width(terminal->host))
85   - return rc;
86   - col++;
87   - }
88   -
89   - // Alocate block, add it to list.
90   - struct ColumnDescription * columndescription = g_new0(struct ColumnDescription,1);
91   - columndescription->begin = col;
92   - rc = g_list_append(rc,columndescription);
93   -
94   - // Get width.
95   - while(hasDataOnColumn(terminal,col++)) {
96   - columndescription->width++;
97   - if(col >= lib3270_get_width(terminal->host))
98   - return rc;
99   - }
100   - }
101   -
102   - return rc;
103   -
104   -}
105   -
106   -/// @brief Get formatted contents as single text.
107   -gchar * v3270_get_copy_as_table(v3270 * terminal, const gchar *delimiter)
108   -{
109   - GString * string = g_string_new("");
110   -
111   - GList * columns = getColumns(terminal);
112   -
113   - debug("columns=%p",columns);
114   -
115   -#ifdef DEBUG
116   - {
117   - GList * column = columns;
118   - while(column)
119   - {
120   - struct ColumnDescription * columndescription = (struct ColumnDescription *) column->data;
121   -
122   - debug("Begin: %u Width: %u",columndescription->begin, columndescription->width);
123   -
124   - column = column->next;
125   - }
126   - }
127   -#endif // DEBUG
128   -
129   - GList * element = terminal->selection.blocks;
130   - unsigned int width = lib3270_get_width(terminal->host);
131   - g_autofree gchar * line = g_malloc0(width+1);
132   - GList * column;
133   -
134   - while(element)
135   - {
136   - lib3270_selection * block = ((lib3270_selection *) element->data);
137   -
138   - unsigned int row, col, src = 0;
139   -
140   - for(row=0; row < block->bounds.height; row++)
141   - {
142   -
143   - // Build text line with selected data.
144   - memset(line,' ',width);
145   - for(col=0; col<block->bounds.width; col++)
146   - {
147   - if(block->contents[src].flags & LIB3270_ATTR_SELECTED)
148   - {
149   - line[block->bounds.col+col] = block->contents[src].chr;
150   - }
151   -
152   - src++;
153   - }
154   -
155   - debug("[%s]",line);
156   -
157   - // Extract columns
158   - for(column = columns; column; column = column->next)
159   - {
160   - struct ColumnDescription * columndescription = (struct ColumnDescription *) column->data;
161   - g_string_append_len(string,line+columndescription->begin,columndescription->width);
162   - if(column->next)
163   - g_string_append(string,delimiter);
164   - }
165   - g_string_append(string,"\n");
166   -
167   - }
168   -
169   - element = g_list_next(element);
170   - }
171   -
172   - g_list_free_full(columns,g_free);
173   -
174   - g_autofree char * text = g_string_free(string,FALSE);
175   - return g_convert(text, -1, "UTF-8", lib3270_get_display_charset(terminal->host), NULL, NULL, NULL);
176   -}
src/clipboard/text.c
... ... @@ -1,197 +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   - #include <clipboard.h>
31   - #include <lib3270/selection.h>
32   -
33   -/*--[ Implement ]------------------------------------------------------------------------------------*/
34   -
35   -/// @brief Get formatted contents as single text.
36   -gchar * v3270_get_copy_as_text(v3270 * terminal)
37   -{
38   - GList * element = terminal->selection.blocks;
39   - GString * string = g_string_new("");
40   -
41   - while(element)
42   - {
43   - lib3270_selection * block = ((lib3270_selection *) element->data);
44   - unsigned int row, col, src = 0;
45   -
46   - for(row=0; row < block->bounds.height; row++)
47   - {
48   - for(col=0; col<block->bounds.width; col++)
49   - {
50   - if(block->contents[src].flags & LIB3270_ATTR_SELECTED)
51   - g_string_append_c(string,block->contents[src].chr);
52   -
53   - src++;
54   -
55   - }
56   - g_string_append_c(string,'\n');
57   - }
58   -
59   - element = g_list_next(element);
60   - }
61   -
62   - g_autofree char * text = g_string_free(string,FALSE);
63   - return g_convert(text, -1, "UTF-8", lib3270_get_display_charset(terminal->host), NULL, NULL, NULL);
64   -
65   -}
66   -
67   -
68   -LIB3270_EXPORT void v3270_paste_text(GtkWidget *widget, const gchar *text, const gchar *encoding)
69   -{
70   - gchar * buffer = NULL;
71   - H3270 * session = v3270_get_session(widget);
72   - const gchar * charset = lib3270_get_display_charset(session);
73   - gboolean next;
74   -
75   - if(!text)
76   - return;
77   - else if(g_ascii_strcasecmp(encoding,charset))
78   - buffer = g_convert(text, -1, charset, encoding, NULL, NULL, NULL);
79   - else
80   - buffer = g_strdup(text);
81   -
82   - if(!buffer)
83   - {
84   - /* Conversion failed, update special chars and try again */
85   - size_t f;
86   -
87   - static const struct _xlat
88   - {
89   - const gchar *from;
90   - const gchar *to;
91   - } xlat[] =
92   - {
93   - { "–", "-" },
94   - { "→", "->" },
95   - { "←", "<-" },
96   - { "©", "(c)" },
97   - { "↔", "<->" },
98   - { "™", "(TM)" },
99   - { "®", "(R)" },
100   - { "“", "\"" },
101   - { "”", "\"" },
102   - { "…", "..." },
103   - { "•", "*" },
104   - { "․", "." },
105   - { "·", "*" },
106   -
107   - };
108   -
109   - gchar *string = g_strdup(text);
110   -
111   - // FIXME (perry#1#): Is there any better way for a "sed" here?
112   - for(f=0;f<G_N_ELEMENTS(xlat);f++)
113   - {
114   - gchar *ptr = g_strstr_len(string,-1,xlat[f].from);
115   -
116   - if(ptr)
117   - {
118   - gchar *old = string;
119   - gchar **tmp = g_strsplit(old,xlat[f].from,-1);
120   - string = g_strjoinv(xlat[f].to,tmp);
121   - g_strfreev(tmp);
122   - g_free(old);
123   - }
124   - }
125   -
126   - buffer = g_convert(string, -1, charset, encoding, NULL, NULL, NULL);
127   -
128   - if(!buffer)
129   - {
130   - // Still failing, convert line by line
131   - gchar **ln = g_strsplit(string,"\n",-1);
132   -
133   - for(f=0;ln[f];f++)
134   - {
135   - GError *error = NULL;
136   - gchar *str = g_convert(ln[f], -1, charset, encoding, NULL, NULL, &error);
137   -
138   - if(!str)
139   - {
140   - GtkWidget *dialog = gtk_message_dialog_new( GTK_WINDOW( gtk_widget_get_toplevel(widget)),
141   - GTK_DIALOG_DESTROY_WITH_PARENT,
142   - GTK_MESSAGE_ERROR,
143   - GTK_BUTTONS_OK,
144   - _( "Can't convert line %lu from %s to %s" ),(unsigned long) (f+1), encoding, charset);
145   -
146   - gtk_window_set_title(GTK_WINDOW(dialog), _( "Charset error" ) );
147   - gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog),"%s\n%s",error->message, ln[f]);
148   -
149   - gtk_dialog_run(GTK_DIALOG (dialog));
150   - gtk_widget_destroy(dialog);
151   -
152   - break;
153   - }
154   - else
155   - {
156   - g_free(str);
157   - }
158   -
159   - }
160   - g_strfreev(ln);
161   -
162   - }
163   -
164   - g_free(string);
165   - }
166   -
167   - if(buffer)
168   - {
169   - /* Remove TABS */
170   - gchar *ptr;
171   -
172   - for(ptr = buffer;*ptr;ptr++)
173   - {
174   - if(*ptr == '\t')
175   - *ptr = ' ';
176   - }
177   - }
178   - else
179   - {
180   - g_signal_emit(widget,v3270_widget_signal[V3270_SIGNAL_PASTENEXT], 0, FALSE);
181   - return;
182   - }
183   -
184   - next = lib3270_paste(session,(unsigned char *) buffer) ? TRUE : FALSE;
185   -
186   - g_free(buffer);
187   -
188   - g_signal_emit(widget,v3270_widget_signal[V3270_SIGNAL_PASTENEXT], 0, next);
189   -
190   -}
191   -
192   -LIB3270_EXPORT gchar * v3270_get_copy(GtkWidget *widget)
193   -{
194   - g_return_val_if_fail(GTK_IS_V3270(widget),NULL);
195   - return v3270_get_copy_as_text(GTK_V3270(widget));
196   -}
197   -
src/clipboard/windows/paste.c
... ... @@ -1,58 +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 selection.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 <windows.h>
31   - #include <clipboard.h>
32   -
33   -/*--[ Implement ]------------------------------------------------------------------------------------*/
34   -
35   -LIB3270_EXPORT void v3270_paste(GtkWidget *widget)
36   -{
37   - HGLOBAL hglb;
38   -
39   - if (!IsClipboardFormatAvailable(CF_TEXT))
40   - return;
41   -
42   - if (!OpenClipboard(NULL))
43   - return;
44   -
45   - hglb = GetClipboardData(CF_TEXT);
46   - if (hglb != NULL)
47   - {
48   - LPTSTR lptstr = GlobalLock(hglb);
49   - if (lptstr != NULL)
50   - {
51   - v3270_paste_text(widget,lptstr,"CP1252");
52   - GlobalUnlock(hglb);
53   - }
54   - }
55   -
56   - CloseClipboard();
57   -
58   -}
src/include/v3270.h
... ... @@ -201,19 +201,18 @@
201 201 LIB3270_EXPORT void v3270_tab(GtkWidget *widget);
202 202 LIB3270_EXPORT void v3270_backtab(GtkWidget *widget);
203 203  
204   - // Cut & Paste
  204 + // Selections
205 205 LIB3270_EXPORT gboolean v3270_get_selection_bounds(GtkWidget *widget, gint *start, gint *end);
206 206 LIB3270_EXPORT void v3270_unselect(GtkWidget *widget);
207 207 LIB3270_EXPORT void v3270_select_all(GtkWidget *widget);
208 208 LIB3270_EXPORT void v3270_select_region(GtkWidget *widget, gint start, gint end);
209 209  
210 210 LIB3270_EXPORT void v3270_copy(GtkWidget *widget, V3270_SELECT_FORMAT mode, gboolean cut);
211   -
212 211 LIB3270_EXPORT void v3270_copy_selection(GtkWidget *widget, V3270_SELECT_FORMAT mode, gboolean cut);
213 212 LIB3270_EXPORT void v3270_append_selection(GtkWidget *widget, gboolean cut);
214 213  
215 214 LIB3270_EXPORT void v3270_paste(GtkWidget *widget);
216   - LIB3270_EXPORT void v3270_paste_text(GtkWidget *widget, const gchar *text, const gchar *encoding);
  215 + LIB3270_EXPORT void v3270_input_text(GtkWidget *widget, const gchar *text, const gchar *encoding);
217 216  
218 217 // Colors
219 218 LIB3270_EXPORT void v3270_set_colors(GtkWidget *widget, const gchar *);
... ...
src/selection/copy.c 0 → 100644
... ... @@ -0,0 +1,129 @@
  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 <clipboard.h>
  31 + #include <lib3270/selection.h>
  32 +
  33 + static void do_copy(v3270 *terminal, gboolean cut)
  34 + {
  35 + lib3270_selection * selection = lib3270_get_selection(terminal->host,cut);
  36 +
  37 + if(selection)
  38 + {
  39 + terminal->selection.blocks = g_list_append(terminal->selection.blocks,selection);
  40 + }
  41 +
  42 + /*
  43 + // Get selection bounds.
  44 + unsigned int row;
  45 + unsigned int col;
  46 + unsigned int width;
  47 + unsigned int height;
  48 +
  49 + if(lib3270_get_selection_rectangle(terminal->host, &row, &col, &width, &height) != 0)
  50 + return;
  51 +
  52 + debug("Selecion rectangle starts on %u,%u with size of %ux%u",
  53 + row, col,
  54 + width, height
  55 + );
  56 +
  57 + // Allocate buffer
  58 + struct selection * selection = g_malloc0(sizeof(struct selection) + (sizeof(struct v3270_character) * (width * height)));
  59 +
  60 + selection->bounds.row = row;
  61 + selection->bounds.col = col;
  62 + selection->bounds.width = width;
  63 + selection->bounds.height = height;
  64 +
  65 + // Copy terminal buffer
  66 + unsigned int r, c;
  67 +
  68 + int pos = 0;
  69 + for(r=0;r < selection->bounds.height; r++)
  70 + {
  71 + // Get starting address.
  72 + int baddr = lib3270_translate_to_address(terminal->host, selection->bounds.row+r+1, selection->bounds.col+1);
  73 + if(baddr < 0)
  74 + {
  75 + g_message("Can't convert coordinate %u,%d",selection->bounds.row+r+1,selection->bounds.col+1);
  76 + gdk_display_beep(gdk_display_get_default());
  77 + return;
  78 + }
  79 +
  80 + for(c=0;c < selection->bounds.width; c++)
  81 + {
  82 + lib3270_get_contents(terminal->host,baddr,baddr,&selection->contents[pos].chr,&selection->contents[pos].attr);
  83 + debug("pos=%d baddr=%u char=%c",pos,baddr,selection->contents[pos].chr);
  84 + pos++;
  85 + baddr++;
  86 + }
  87 +
  88 + }
  89 +
  90 + terminal->selection.blocks = g_list_append(terminal->selection.blocks,selection);
  91 + */
  92 + }
  93 +
  94 + LIB3270_EXPORT void v3270_copy_selection(GtkWidget *widget, V3270_SELECT_FORMAT format, gboolean cut)
  95 + {
  96 + g_return_if_fail(GTK_IS_V3270(widget));
  97 +
  98 + v3270 * terminal = GTK_V3270(widget);
  99 +
  100 + // Have data? Clear it?
  101 + v3270_clear_selection(terminal);
  102 +
  103 + terminal->selection.format = format;
  104 + do_copy(terminal,cut);
  105 +
  106 + v3270_update_system_clipboard(widget);
  107 +
  108 +/*
  109 +#ifdef DEBUG
  110 + gchar *columns = v3270_get_copy_as_table(terminal,"---");
  111 + debug("Output:\n%s",columns);
  112 + g_free(columns);
  113 +#endif // DEBUG
  114 +*/
  115 +
  116 + }
  117 +
  118 + LIB3270_EXPORT void v3270_append_selection(GtkWidget *widget, gboolean cut)
  119 + {
  120 + g_return_if_fail(GTK_IS_V3270(widget));
  121 +
  122 + v3270 * terminal = GTK_V3270(widget);
  123 +
  124 + do_copy(terminal,cut);
  125 +
  126 + v3270_update_system_clipboard(widget);
  127 +
  128 + }
  129 +
... ...
src/selection/linux/paste.c 0 → 100644
... ... @@ -0,0 +1,75 @@
  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 selection.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 <clipboard.h>
  31 +
  32 +/*--[ Implement ]------------------------------------------------------------------------------------*/
  33 +
  34 +static void text_received(G_GNUC_UNUSED GtkClipboard *clipboard, const gchar *text, GtkWidget *widget)
  35 +{
  36 + v3270_input_text(widget,text,"UTF-8");
  37 +}
  38 +
  39 +static gboolean has_target(const gchar *name, const GdkAtom *atoms, const gint n_atoms)
  40 +{
  41 + gint ix;
  42 +
  43 + for(ix = 0; ix < n_atoms; ix++)
  44 + {
  45 + if(!g_ascii_strcasecmp(name,gdk_atom_name(atoms[ix])))
  46 + return TRUE;
  47 +
  48 + }
  49 +
  50 + return FALSE;
  51 +}
  52 +
  53 +static void targets_received(GtkClipboard *clipboard, GdkAtom *atoms, gint n_atoms, GtkWidget *widget)
  54 +{
  55 + if(has_target("application/x-" PACKAGE_NAME, atoms, n_atoms))
  56 + {
  57 + debug("Clipboard as TN3270 \"%s\" data",PACKAGE_NAME);
  58 + return;
  59 + }
  60 +
  61 + // No special format available, request it as text.
  62 + gtk_clipboard_request_text(clipboard, (GtkClipboardTextReceivedFunc) text_received, (gpointer) widget);
  63 +
  64 +}
  65 +
  66 +LIB3270_EXPORT void v3270_paste(GtkWidget *widget)
  67 +{
  68 + g_return_if_fail(GTK_IS_V3270(widget));
  69 +
  70 + GtkClipboard * clipboard = gtk_widget_get_clipboard(widget,GTK_V3270(widget)->selection.target);
  71 +
  72 + gtk_clipboard_request_targets(clipboard, (GtkClipboardTargetsReceivedFunc) targets_received, (gpointer) widget);
  73 +
  74 +}
  75 +
... ...
src/selection/selection.c 0 → 100644
... ... @@ -0,0 +1,219 @@
  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 selection.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 <clipboard.h>
  31 + #include <lib3270/selection.h>
  32 +
  33 +/*--[ Implement ]------------------------------------------------------------------------------------*/
  34 +
  35 +static void clipboard_clear(G_GNUC_UNUSED GtkClipboard *clipboard, G_GNUC_UNUSED GObject *obj)
  36 +{
  37 + v3270 * terminal = GTK_V3270(obj);
  38 +
  39 + if(!lib3270_get_toggle(terminal->host,LIB3270_TOGGLE_KEEP_SELECTED))
  40 + {
  41 + v3270_unselect(GTK_WIDGET(obj));
  42 + v3270_clear_selection(terminal);
  43 + }
  44 +
  45 +}
  46 +
  47 +static void clipboard_get(G_GNUC_UNUSED GtkClipboard *clipboard, GtkSelectionData *selection, guint target, GObject *obj)
  48 +{
  49 + v3270 * terminal = GTK_V3270(obj);
  50 +
  51 + if(!terminal->selection.blocks)
  52 + {
  53 + return;
  54 + }
  55 +
  56 + switch(target)
  57 + {
  58 + case CLIPBOARD_TYPE_TEXT: // Get clipboard contents as text
  59 + {
  60 + gchar *text;
  61 +
  62 + if(terminal->selection.format == V3270_SELECT_TABLE)
  63 + {
  64 + text = v3270_get_copy_as_table(terminal,"\t");
  65 + }
  66 + else
  67 + {
  68 + text = v3270_get_copy_as_text(terminal);
  69 + }
  70 + gtk_selection_data_set_text(selection,text,-1);
  71 + g_free(text);
  72 + }
  73 + break;
  74 +
  75 + case CLIPBOARD_TYPE_CSV:
  76 + {
  77 + g_autofree gchar *text = v3270_get_copy_as_table(terminal,";");
  78 + debug("Selection:\n%s",text);
  79 + gtk_selection_data_set(
  80 + selection,
  81 + gdk_atom_intern_static_string("text/csv"),
  82 + 8,
  83 + (guchar *) text,
  84 + strlen(text)
  85 + );
  86 + }
  87 + break;
  88 +
  89 + default:
  90 + g_warning("Unexpected clipboard type %d\n",target);
  91 + }
  92 +}
  93 +
  94 +/**
  95 + * Clear clipboard contents.
  96 + *
  97 + * @param terminal Pointer to the terminal Widget.
  98 + *
  99 + */
  100 +void v3270_clear_selection(v3270 *terminal)
  101 +{
  102 + if(terminal->selection.blocks)
  103 + {
  104 + g_list_free_full(terminal->selection.blocks,(GDestroyNotify) lib3270_free);
  105 + terminal->selection.blocks = NULL;
  106 + }
  107 +}
  108 +
  109 +/**
  110 + * Get lib3270 selection as a g_malloc buffer.
  111 + *
  112 + * @param widget Widget containing the desired section.
  113 + *
  114 + * @return NULL if error, otherwise the selected buffer contents (release with g_free).
  115 + *
  116 + */
  117 +LIB3270_EXPORT gchar * v3270_get_selected(GtkWidget *widget, gboolean cut)
  118 +{
  119 + lib3270_autoptr(char) text = NULL;
  120 +
  121 + g_return_val_if_fail(GTK_IS_V3270(widget),NULL);
  122 +
  123 + if(cut)
  124 + text = lib3270_cut_selected(GTK_V3270(widget)->host);
  125 + else
  126 + text = lib3270_get_selected(GTK_V3270(widget)->host);
  127 +
  128 + if(text)
  129 + return g_convert(text, -1, "UTF-8", lib3270_get_display_charset(GTK_V3270(widget)->host), NULL, NULL, NULL);
  130 +
  131 + return NULL;
  132 +}
  133 +
  134 +void v3270_update_system_clipboard(GtkWidget *widget)
  135 +{
  136 + v3270 * terminal = GTK_V3270(widget);
  137 +
  138 + if(!terminal->selection.blocks)
  139 + {
  140 + // No clipboard data, return.
  141 + g_signal_emit(widget,v3270_widget_signal[V3270_SIGNAL_CLIPBOARD], 0, FALSE);
  142 + return;
  143 + }
  144 +
  145 + // Has clipboard data, inform system.
  146 + GtkClipboard * clipboard = gtk_widget_get_clipboard(widget,terminal->selection.target);
  147 +
  148 + // Create target list
  149 + //
  150 + // Reference: https://cpp.hotexamples.com/examples/-/-/g_list_insert_sorted/cpp-g_list_insert_sorted-function-examples.html
  151 + //
  152 + static const GtkTargetEntry internal_targets[] = {
  153 + { "text/csv", 0, CLIPBOARD_TYPE_CSV }
  154 + };
  155 +
  156 + GtkTargetList * list = gtk_target_list_new(internal_targets, G_N_ELEMENTS(internal_targets));
  157 + GtkTargetEntry * targets;
  158 + int n_targets;
  159 +
  160 + gtk_target_list_add_text_targets(list, CLIPBOARD_TYPE_TEXT);
  161 +
  162 + targets = gtk_target_table_new_from_list(list, &n_targets);
  163 +
  164 +#ifdef DEBUG
  165 + {
  166 + int ix;
  167 + for(ix = 0; ix < n_targets; ix++) {
  168 + debug("target(%d)=\"%s\"",ix,targets[ix].target);
  169 + }
  170 + }
  171 +#endif // DEBUG
  172 +
  173 + if(gtk_clipboard_set_with_owner(
  174 + clipboard,
  175 + targets,
  176 + n_targets,
  177 + (GtkClipboardGetFunc) clipboard_get,
  178 + (GtkClipboardClearFunc) clipboard_clear,
  179 + G_OBJECT(widget)
  180 + ))
  181 + {
  182 + gtk_clipboard_set_can_store(clipboard,targets,1);
  183 + }
  184 +
  185 + gtk_target_table_free(targets, n_targets);
  186 + gtk_target_list_unref(list);
  187 +
  188 + g_signal_emit(widget,v3270_widget_signal[V3270_SIGNAL_CLIPBOARD], 0, TRUE);
  189 +
  190 +}
  191 +
  192 +LIB3270_EXPORT void v3270_unselect(GtkWidget *widget)
  193 +{
  194 + v3270_disable_updates(widget);
  195 + lib3270_unselect(v3270_get_session(widget));
  196 + v3270_enable_updates(widget);
  197 +}
  198 +
  199 +gboolean v3270_get_selection_bounds(GtkWidget *widget, gint *start, gint *end)
  200 +{
  201 + g_return_val_if_fail(GTK_IS_V3270(widget),FALSE);
  202 + return lib3270_get_selection_bounds(GTK_V3270(widget)->host,start,end) == 0 ? FALSE : TRUE;
  203 +}
  204 +
  205 +LIB3270_EXPORT void v3270_select_region(GtkWidget *widget, gint start, gint end)
  206 +{
  207 + g_return_if_fail(GTK_IS_V3270(widget));
  208 + lib3270_select_region(GTK_V3270(widget)->host,start,end);
  209 +}
  210 +
  211 +LIB3270_EXPORT void v3270_select_all(GtkWidget *widget)
  212 +{
  213 + g_return_if_fail(GTK_IS_V3270(widget));
  214 + v3270_disable_updates(widget);
  215 + lib3270_select_all(v3270_get_session(widget));
  216 + v3270_enable_updates(widget);
  217 +}
  218 +
  219 +
... ...
src/selection/table.c 0 → 100644
... ... @@ -0,0 +1,176 @@
  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 <clipboard.h>
  31 + #include <ctype.h>
  32 + #include <lib3270/selection.h>
  33 +
  34 + struct ColumnDescription {
  35 + unsigned int begin;
  36 + unsigned int width;
  37 + };
  38 +
  39 +/*--[ Implement ]------------------------------------------------------------------------------------*/
  40 +
  41 +/// @brief Check if column has data.
  42 +static gboolean hasDataOnColumn(v3270 * terminal, unsigned int col)
  43 +{
  44 + GList * element = terminal->selection.blocks;
  45 +
  46 + while(element)
  47 + {
  48 + lib3270_selection * block = ((lib3270_selection *) element->data);
  49 +
  50 + if( (col >= block->bounds.col) && ( col < (block->bounds.col + block->bounds.width)) )
  51 + {
  52 + unsigned int pos = col-block->bounds.col;
  53 + unsigned int row;
  54 +
  55 + for(row = 0; row < block->bounds.height; row++)
  56 + {
  57 + if( (block->contents[pos].flags & LIB3270_ATTR_SELECTED) && !isspace(block->contents[pos].chr))
  58 + {
  59 + return TRUE;
  60 + }
  61 + pos += block->bounds.width;
  62 + }
  63 +
  64 + }
  65 +
  66 + element = g_list_next(element);
  67 + }
  68 +
  69 + return FALSE;
  70 +}
  71 +
  72 +/// @brief Get column list.
  73 +GList * getColumns(v3270 * terminal)
  74 +{
  75 + unsigned int col = 0;
  76 + GList *rc = NULL;
  77 +
  78 + while(col < lib3270_get_width(terminal->host)) {
  79 +
  80 + // debug("col(%u): %s", col, hasDataOnColumn(terminal,col) ? "yes" : "no");
  81 +
  82 + // Get first column.
  83 + while(!hasDataOnColumn(terminal,col)) {
  84 + if(col >= lib3270_get_width(terminal->host))
  85 + return rc;
  86 + col++;
  87 + }
  88 +
  89 + // Alocate block, add it to list.
  90 + struct ColumnDescription * columndescription = g_new0(struct ColumnDescription,1);
  91 + columndescription->begin = col;
  92 + rc = g_list_append(rc,columndescription);
  93 +
  94 + // Get width.
  95 + while(hasDataOnColumn(terminal,col++)) {
  96 + columndescription->width++;
  97 + if(col >= lib3270_get_width(terminal->host))
  98 + return rc;
  99 + }
  100 + }
  101 +
  102 + return rc;
  103 +
  104 +}
  105 +
  106 +/// @brief Get formatted contents as single text.
  107 +gchar * v3270_get_copy_as_table(v3270 * terminal, const gchar *delimiter)
  108 +{
  109 + GString * string = g_string_new("");
  110 +
  111 + GList * columns = getColumns(terminal);
  112 +
  113 + debug("columns=%p",columns);
  114 +
  115 +#ifdef DEBUG
  116 + {
  117 + GList * column = columns;
  118 + while(column)
  119 + {
  120 + struct ColumnDescription * columndescription = (struct ColumnDescription *) column->data;
  121 +
  122 + debug("Begin: %u Width: %u",columndescription->begin, columndescription->width);
  123 +
  124 + column = column->next;
  125 + }
  126 + }
  127 +#endif // DEBUG
  128 +
  129 + GList * element = terminal->selection.blocks;
  130 + unsigned int width = lib3270_get_width(terminal->host);
  131 + g_autofree gchar * line = g_malloc0(width+1);
  132 + GList * column;
  133 +
  134 + while(element)
  135 + {
  136 + lib3270_selection * block = ((lib3270_selection *) element->data);
  137 +
  138 + unsigned int row, col, src = 0;
  139 +
  140 + for(row=0; row < block->bounds.height; row++)
  141 + {
  142 +
  143 + // Build text line with selected data.
  144 + memset(line,' ',width);
  145 + for(col=0; col<block->bounds.width; col++)
  146 + {
  147 + if(block->contents[src].flags & LIB3270_ATTR_SELECTED)
  148 + {
  149 + line[block->bounds.col+col] = block->contents[src].chr;
  150 + }
  151 +
  152 + src++;
  153 + }
  154 +
  155 + debug("[%s]",line);
  156 +
  157 + // Extract columns
  158 + for(column = columns; column; column = column->next)
  159 + {
  160 + struct ColumnDescription * columndescription = (struct ColumnDescription *) column->data;
  161 + g_string_append_len(string,line+columndescription->begin,columndescription->width);
  162 + if(column->next)
  163 + g_string_append(string,delimiter);
  164 + }
  165 + g_string_append(string,"\n");
  166 +
  167 + }
  168 +
  169 + element = g_list_next(element);
  170 + }
  171 +
  172 + g_list_free_full(columns,g_free);
  173 +
  174 + g_autofree char * text = g_string_free(string,FALSE);
  175 + return g_convert(text, -1, "UTF-8", lib3270_get_display_charset(terminal->host), NULL, NULL, NULL);
  176 +}
... ...
src/selection/text.c 0 → 100644
... ... @@ -0,0 +1,203 @@
  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 <clipboard.h>
  31 + #include <lib3270/selection.h>
  32 +
  33 +/*--[ Implement ]------------------------------------------------------------------------------------*/
  34 +
  35 +/// @brief Get formatted contents as single text.
  36 +gchar * v3270_get_copy_as_text(v3270 * terminal)
  37 +{
  38 + GList * element = terminal->selection.blocks;
  39 + GString * string = g_string_new("");
  40 +
  41 + while(element)
  42 + {
  43 + lib3270_selection * block = ((lib3270_selection *) element->data);
  44 + unsigned int row, col, src = 0;
  45 +
  46 + for(row=0; row < block->bounds.height; row++)
  47 + {
  48 + for(col=0; col<block->bounds.width; col++)
  49 + {
  50 + if(block->contents[src].flags & LIB3270_ATTR_SELECTED)
  51 + g_string_append_c(string,block->contents[src].chr);
  52 +
  53 + src++;
  54 +
  55 + }
  56 + g_string_append_c(string,'\n');
  57 + }
  58 +
  59 + element = g_list_next(element);
  60 + }
  61 +
  62 + g_autofree char * text = g_string_free(string,FALSE);
  63 + return g_convert(text, -1, "UTF-8", lib3270_get_display_charset(terminal->host), NULL, NULL, NULL);
  64 +
  65 +}
  66 +
  67 +
  68 +LIB3270_EXPORT void v3270_input_text(GtkWidget *widget, const gchar *text, const gchar *encoding)
  69 +{
  70 + gchar * buffer = NULL;
  71 + H3270 * session = v3270_get_session(widget);
  72 + const gchar * charset = lib3270_get_display_charset(session);
  73 + gboolean next;
  74 +
  75 + if(!text)
  76 + return;
  77 + else if(g_ascii_strcasecmp(encoding,charset))
  78 + buffer = g_convert(text, -1, charset, encoding, NULL, NULL, NULL);
  79 + else
  80 + buffer = g_strdup(text);
  81 +
  82 + if(!buffer)
  83 + {
  84 + /* Conversion failed, update special chars and try again */
  85 + size_t f;
  86 +
  87 + static const struct _xlat
  88 + {
  89 + const gchar *from;
  90 + const gchar *to;
  91 + } xlat[] =
  92 + {
  93 + { "–", "-" },
  94 + { "→", "->" },
  95 + { "←", "<-" },
  96 + { "©", "(c)" },
  97 + { "↔", "<->" },
  98 + { "™", "(TM)" },
  99 + { "®", "(R)" },
  100 + { "“", "\"" },
  101 + { "”", "\"" },
  102 + { "…", "..." },
  103 + { "•", "*" },
  104 + { "․", "." },
  105 + { "·", "*" },
  106 +
  107 + };
  108 +
  109 + gchar *string = g_strdup(text);
  110 +
  111 + // FIXME (perry#1#): Is there any better way for a "sed" here?
  112 + for(f=0;f<G_N_ELEMENTS(xlat);f++)
  113 + {
  114 + gchar *ptr = g_strstr_len(string,-1,xlat[f].from);
  115 +
  116 + if(ptr)
  117 + {
  118 + gchar *old = string;
  119 + gchar **tmp = g_strsplit(old,xlat[f].from,-1);
  120 + string = g_strjoinv(xlat[f].to,tmp);
  121 + g_strfreev(tmp);
  122 + g_free(old);
  123 + }
  124 + }
  125 +
  126 + buffer = g_convert(string, -1, charset, encoding, NULL, NULL, NULL);
  127 +
  128 + if(!buffer)
  129 + {
  130 + // Still failing, convert line by line
  131 + gchar **ln = g_strsplit(string,"\n",-1);
  132 +
  133 + for(f=0;ln[f];f++)
  134 + {
  135 + GError *error = NULL;
  136 + gchar *str = g_convert(ln[f], -1, charset, encoding, NULL, NULL, &error);
  137 +
  138 + if(!str)
  139 + {
  140 + GtkWidget *dialog = gtk_message_dialog_new( GTK_WINDOW( gtk_widget_get_toplevel(widget)),
  141 + GTK_DIALOG_DESTROY_WITH_PARENT,
  142 + GTK_MESSAGE_ERROR,
  143 + GTK_BUTTONS_OK,
  144 + _( "Can't convert line %lu from %s to %s" ),(unsigned long) (f+1), encoding, charset);
  145 +
  146 + gtk_window_set_title(GTK_WINDOW(dialog), _( "Charset error" ) );
  147 +
  148 + if(error)
  149 + {
  150 + gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog),"%s\n%s",error->message, ln[f]);
  151 + g_error_free(error);
  152 + error = NULL;
  153 + }
  154 +
  155 + gtk_dialog_run(GTK_DIALOG (dialog));
  156 + gtk_widget_destroy(dialog);
  157 +
  158 + break;
  159 + }
  160 + else
  161 + {
  162 + g_free(str);
  163 + }
  164 +
  165 + }
  166 + g_strfreev(ln);
  167 +
  168 + }
  169 +
  170 + g_free(string);
  171 + }
  172 +
  173 + if(buffer)
  174 + {
  175 + /* Remove TABS */
  176 + gchar *ptr;
  177 +
  178 + for(ptr = buffer;*ptr;ptr++)
  179 + {
  180 + if(*ptr == '\t')
  181 + *ptr = ' ';
  182 + }
  183 + }
  184 + else
  185 + {
  186 + g_signal_emit(widget,v3270_widget_signal[V3270_SIGNAL_PASTENEXT], 0, FALSE);
  187 + return;
  188 + }
  189 +
  190 + next = lib3270_paste(session,(unsigned char *) buffer) ? TRUE : FALSE;
  191 +
  192 + g_free(buffer);
  193 +
  194 + g_signal_emit(widget,v3270_widget_signal[V3270_SIGNAL_PASTENEXT], 0, next);
  195 +
  196 +}
  197 +
  198 +LIB3270_EXPORT gchar * v3270_get_copy(GtkWidget *widget)
  199 +{
  200 + g_return_val_if_fail(GTK_IS_V3270(widget),NULL);
  201 + return v3270_get_copy_as_text(GTK_V3270(widget));
  202 +}
  203 +
... ...
src/selection/windows/paste.c 0 → 100644
... ... @@ -0,0 +1,61 @@
  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 selection.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 <windows.h>
  31 + #include <clipboard.h>
  32 +
  33 +/*--[ Implement ]------------------------------------------------------------------------------------*/
  34 +
  35 +LIB3270_EXPORT void v3270_paste(GtkWidget *widget)
  36 +{
  37 + g_return_if_fail(GTK_IS_V3270(session));
  38 +
  39 + if (!OpenClipboard(NULL))
  40 + return;
  41 +
  42 + if (IsClipboardFormatAvailable(CF_TEXT))
  43 + {
  44 + // Got text formatted clipboard.
  45 + HGLOBAL hglb;
  46 +
  47 + hglb = GetClipboardData(CF_TEXT);
  48 + if (hglb != NULL)
  49 + {
  50 + LPTSTR lptstr = GlobalLock(hglb);
  51 + if (lptstr != NULL)
  52 + {
  53 + v3270_input_text(widget,lptstr,"CP1252");
  54 + GlobalUnlock(hglb);
  55 + }
  56 + }
  57 + }
  58 +
  59 + CloseClipboard();
  60 +
  61 +}
... ...
src/testprogram/testprogram.c
... ... @@ -218,6 +218,11 @@ static void ft_clicked(GtkButton *button, GtkWidget *terminal)
218 218  
219 219 }
220 220  
  221 +static void paste_clicked(GtkButton *button, GtkWidget *terminal)
  222 +{
  223 + v3270_paste(terminal);
  224 +}
  225 +
221 226 static void color_clicked(GtkButton G_GNUC_UNUSED(*button), GtkWidget *terminal)
222 227 {
223 228 GtkWidget * dialog = v3270_dialog_new(terminal, _("Color setup"), _("_Save"));
... ... @@ -296,7 +301,8 @@ static void activate(GtkApplication* app, G_GNUC_UNUSED gpointer user_data) {
296 301 { "gtk-select-color", G_CALLBACK(color_clicked), "Edit or change color scheme" },
297 302 { "gtk-home", G_CALLBACK(host_clicked), "Configure host" },
298 303 { "gtk-print", G_CALLBACK(print_clicked), "Print screen contents" },
299   - { "gtk-harddisk", G_CALLBACK(ft_clicked), "Open file transfer dialog" }
  304 + { "gtk-harddisk", G_CALLBACK(ft_clicked), "Open file transfer dialog" },
  305 + { "gtk-paste", G_CALLBACK(paste_clicked), "Paste data" }
300 306 };
301 307  
302 308 GtkWidget * toolbar = gtk_toolbar_new();
... ...
v3270.cbp
... ... @@ -42,24 +42,6 @@
42 42 <Add option="-fPIC" />
43 43 </Linker>
44 44 <Unit filename="configure.ac" />
45   - <Unit filename="src/clipboard/copy.c">
46   - <Option compilerVar="CC" />
47   - </Unit>
48   - <Unit filename="src/clipboard/linux/paste.c">
49   - <Option compilerVar="CC" />
50   - </Unit>
51   - <Unit filename="src/clipboard/selection.c">
52   - <Option compilerVar="CC" />
53   - </Unit>
54   - <Unit filename="src/clipboard/table.c">
55   - <Option compilerVar="CC" />
56   - </Unit>
57   - <Unit filename="src/clipboard/text.c">
58   - <Option compilerVar="CC" />
59   - </Unit>
60   - <Unit filename="src/clipboard/windows/paste.c">
61   - <Option compilerVar="CC" />
62   - </Unit>
63 45 <Unit filename="src/dialogs/colors.c">
64 46 <Option compilerVar="CC" />
65 47 </Unit>
... ... @@ -161,6 +143,24 @@
161 143 <Unit filename="src/include/v3270/ftprogress.h" />
162 144 <Unit filename="src/include/v3270/print.h" />
163 145 <Unit filename="src/include/v3270/trace.h" />
  146 + <Unit filename="src/selection/copy.c">
  147 + <Option compilerVar="CC" />
  148 + </Unit>
  149 + <Unit filename="src/selection/linux/paste.c">
  150 + <Option compilerVar="CC" />
  151 + </Unit>
  152 + <Unit filename="src/selection/selection.c">
  153 + <Option compilerVar="CC" />
  154 + </Unit>
  155 + <Unit filename="src/selection/table.c">
  156 + <Option compilerVar="CC" />
  157 + </Unit>
  158 + <Unit filename="src/selection/text.c">
  159 + <Option compilerVar="CC" />
  160 + </Unit>
  161 + <Unit filename="src/selection/windows/paste.c">
  162 + <Option compilerVar="CC" />
  163 + </Unit>
164 164 <Unit filename="src/terminal/accessible.c">
165 165 <Option compilerVar="CC" />
166 166 </Unit>
... ...