Commit dab61a039c5ce972ab080978c96d7cc4989decdc

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

Working on new clipboard manager.

src/clipboard/copy.c
@@ -30,57 +30,92 @@ @@ -30,57 +30,92 @@
30 #include <clipboard.h> 30 #include <clipboard.h>
31 #include <lib3270/selection.h> 31 #include <lib3270/selection.h>
32 32
33 - LIB3270_EXPORT void v3270_copy(GtkWidget *widget, V3270_SELECT_FORMAT format, gboolean cut) 33 + static void do_copy(v3270 *terminal)
34 { 34 {
35 -  
36 - g_return_if_fail(GTK_IS_V3270(widget));  
37 -  
38 - v3270 * terminal = GTK_V3270(widget);  
39 -  
40 - terminal->selection.format = format;  
41 -  
42 - // Have data? Clear it?  
43 - v3270_clear_clipboard(terminal);  
44 -  
45 // Get selection bounds. 35 // Get selection bounds.
  36 + unsigned int row;
  37 + unsigned int col;
  38 + unsigned int width;
  39 + unsigned int height;
46 40
47 - if(lib3270_get_selection_rectangle(terminal->host, &terminal->selection.bounds.row, &terminal->selection.bounds.col, &terminal->selection.bounds.width, &terminal->selection.bounds.height) != 0) 41 + if(lib3270_get_selection_rectangle(terminal->host, &row, &col, &width, &height) != 0)
48 return; 42 return;
49 43
50 debug("Selecion rectangle starts on %u,%u with size of %ux%u", 44 debug("Selecion rectangle starts on %u,%u with size of %ux%u",
51 - terminal->selection.bounds.row, terminal->selection.bounds.col,  
52 - terminal->selection.bounds.width, terminal->selection.bounds.height 45 + row, col,
  46 + width, height
53 ); 47 );
54 48
  49 + // Allocate buffer
  50 + struct selection * selection = g_malloc0(sizeof(struct selection) + (sizeof(struct v3270_character) * (width * height)));
  51 +
  52 + selection->bounds.row = row;
  53 + selection->bounds.col = col;
  54 + selection->bounds.width = width;
  55 + selection->bounds.height = height;
55 56
56 // Copy terminal buffer 57 // Copy terminal buffer
57 unsigned int r, c; 58 unsigned int r, c;
58 59
59 - terminal->selection.contents = g_new0(struct v3270_character,(terminal->selection.bounds.width * terminal->selection.bounds.height));  
60 -  
61 int pos = 0; 60 int pos = 0;
62 - for(r=0;r < terminal->selection.bounds.height; r++) 61 + for(r=0;r < selection->bounds.height; r++)
63 { 62 {
64 // Get starting address. 63 // Get starting address.
65 - int baddr = lib3270_translate_to_address(terminal->host, terminal->selection.bounds.row+r+1, terminal->selection.bounds.col+1); 64 + int baddr = lib3270_translate_to_address(terminal->host, selection->bounds.row+r+1, selection->bounds.col+1);
66 if(baddr < 0) 65 if(baddr < 0)
67 { 66 {
68 - g_message("Can't convert coordinate %u,%d",terminal->selection.bounds.row+r+1,terminal->selection.bounds.col+1); 67 + g_message("Can't convert coordinate %u,%d",selection->bounds.row+r+1,selection->bounds.col+1);
69 gdk_display_beep(gdk_display_get_default()); 68 gdk_display_beep(gdk_display_get_default());
70 return; 69 return;
71 } 70 }
72 71
73 - for(c=0;c < terminal->selection.bounds.width; c++) 72 + for(c=0;c < selection->bounds.width; c++)
74 { 73 {
75 - lib3270_get_contents(terminal->host,baddr,baddr,&terminal->selection.contents[pos].chr,&terminal->selection.contents[pos].attr);  
76 - debug("pos=%d baddr=%u char=%c",pos,baddr,terminal->selection.contents[pos].chr); 74 + lib3270_get_contents(terminal->host,baddr,baddr,&selection->contents[pos].chr,&selection->contents[pos].attr);
  75 + debug("pos=%d baddr=%u char=%c",pos,baddr,selection->contents[pos].chr);
77 pos++; 76 pos++;
78 baddr++; 77 baddr++;
79 } 78 }
80 79
81 } 80 }
82 81
  82 + terminal->selection.blocks = g_list_append(terminal->selection.blocks,selection);
  83 +
  84 + }
  85 +
  86 + LIB3270_EXPORT void v3270_copy_selection(GtkWidget *widget, V3270_SELECT_FORMAT format, gboolean cut)
  87 + {
  88 + g_return_if_fail(GTK_IS_V3270(widget));
  89 +
  90 + v3270 * terminal = GTK_V3270(widget);
  91 +
  92 + // Have data? Clear it?
  93 + v3270_clear_clipboard(terminal);
  94 +
  95 + terminal->selection.format = format;
  96 + do_copy(terminal);
  97 +
83 v3270_update_system_clipboard(widget); 98 v3270_update_system_clipboard(widget);
84 99
  100 + if(cut)
  101 + {
  102 + lib3270_erase_selected(terminal->host);
  103 + }
  104 + }
  105 +
  106 + LIB3270_EXPORT void v3270_append_selection(GtkWidget *widget, gboolean cut)
  107 + {
  108 + g_return_if_fail(GTK_IS_V3270(widget));
  109 +
  110 + v3270 * terminal = GTK_V3270(widget);
  111 +
  112 + do_copy(terminal);
  113 +
  114 + v3270_update_system_clipboard(widget);
  115 +
  116 + if(cut)
  117 + {
  118 + lib3270_erase_selected(terminal->host);
  119 + }
85 } 120 }
86 121
src/clipboard/selection.c
@@ -44,45 +44,48 @@ static void clipboard_clear(G_GNUC_UNUSED GtkClipboard *clipboard, G_GNUC_UNUSED @@ -44,45 +44,48 @@ static void clipboard_clear(G_GNUC_UNUSED GtkClipboard *clipboard, G_GNUC_UNUSED
44 } 44 }
45 45
46 /// @brief Get formatted contents as single text. 46 /// @brief Get formatted contents as single text.
47 -static gchar * get_selection_as_text(v3270 * terminal) 47 +static gchar * get_copy_as_text(v3270 * terminal)
48 { 48 {
49 - // Has formatted clipboard, convert it to text.  
50 - unsigned int r, c, src = 0, dst = 0;  
51 - g_autofree char * text = g_malloc0( (terminal->selection.bounds.width * terminal->selection.bounds.height) + terminal->selection.bounds.height + 2); 49 + GList * element = terminal->selection.blocks;
  50 + GString * string = g_string_new("");
52 51
53 - for(r=0;r < terminal->selection.bounds.height;r++) 52 + while(element)
54 { 53 {
55 - for(c=0;c<terminal->selection.bounds.width;c++) 54 + struct selection * block = ((struct selection *) element->data);
  55 + unsigned int row, col, src = 0;
  56 +
  57 + for(row=0; row < block->bounds.height; row++)
56 { 58 {
57 - if(terminal->selection.contents[src].attr & LIB3270_ATTR_SELECTED)  
58 - text[dst++] = terminal->selection.contents[src].chr; 59 + for(col=0; col<block->bounds.width; col++)
  60 + {
  61 + if(block->contents[src].attr & LIB3270_ATTR_SELECTED)
  62 + g_string_append_c(string,block->contents[src].chr);
  63 +
  64 + src++;
59 65
60 - src++; 66 + }
  67 + g_string_append_c(string,'\n');
61 } 68 }
62 69
63 - text[dst++] = '\n'; 70 + element = g_list_next(element);
64 } 71 }
65 72
  73 + g_autofree char * text = g_string_free(string,FALSE);
66 return g_convert(text, -1, "UTF-8", lib3270_get_display_charset(terminal->host), NULL, NULL, NULL); 74 return g_convert(text, -1, "UTF-8", lib3270_get_display_charset(terminal->host), NULL, NULL, NULL);
  75 +
67 } 76 }
68 77
69 static void clipboard_get(G_GNUC_UNUSED GtkClipboard *clipboard, GtkSelectionData *selection, guint target, GObject *obj) 78 static void clipboard_get(G_GNUC_UNUSED GtkClipboard *clipboard, GtkSelectionData *selection, guint target, GObject *obj)
70 { 79 {
71 v3270 * terminal = GTK_V3270(obj); 80 v3270 * terminal = GTK_V3270(obj);
72 81
73 - debug("%s target=%u selection from with %ux%u",  
74 - __FUNCTION__,  
75 - (unsigned int) target,  
76 - terminal->selection.bounds.width, terminal->selection.bounds.height  
77 - );  
78 -  
79 switch(target) 82 switch(target)
80 { 83 {
81 - case CLIPBOARD_TYPE_TEXT: /* Get clipboard contents as text */ 84 + case CLIPBOARD_TYPE_TEXT: // Get clipboard contents as text
82 85
83 - if(terminal->selection.contents) 86 + if(terminal->selection.blocks)
84 { 87 {
85 - g_autofree gchar * converted = get_selection_as_text(terminal); 88 + g_autofree gchar * converted = get_copy_as_text(terminal);
86 gtk_selection_data_set_text(selection,converted,-1); 89 gtk_selection_data_set_text(selection,converted,-1);
87 } 90 }
88 91
@@ -101,15 +104,11 @@ static void clipboard_get(G_GNUC_UNUSED GtkClipboard *clipboard, GtkSelectionDa @@ -101,15 +104,11 @@ static void clipboard_get(G_GNUC_UNUSED GtkClipboard *clipboard, GtkSelectionDa
101 */ 104 */
102 void v3270_clear_clipboard(v3270 *terminal) 105 void v3270_clear_clipboard(v3270 *terminal)
103 { 106 {
104 - memset(&terminal->selection.bounds,0,sizeof(terminal->selection.bounds));  
105 -  
106 - if(terminal->selection.contents) 107 + if(terminal->selection.blocks)
107 { 108 {
108 - g_free(terminal->selection.contents);  
109 - terminal->selection.contents = NULL; 109 + g_list_free_full(terminal->selection.blocks,g_free);
  110 + terminal->selection.blocks = NULL;
110 } 111 }
111 -  
112 -// terminal->selection.text = lib3270_free(terminal->selection.text);  
113 } 112 }
114 113
115 /** 114 /**
@@ -122,11 +121,14 @@ void v3270_clear_clipboard(v3270 *terminal) @@ -122,11 +121,14 @@ void v3270_clear_clipboard(v3270 *terminal)
122 */ 121 */
123 LIB3270_EXPORT gchar * v3270_get_selected(GtkWidget *widget, gboolean cut) 122 LIB3270_EXPORT gchar * v3270_get_selected(GtkWidget *widget, gboolean cut)
124 { 123 {
125 - const char *text; 124 + lib3270_autoptr(char) text = NULL;
126 125
127 g_return_val_if_fail(GTK_IS_V3270(widget),NULL); 126 g_return_val_if_fail(GTK_IS_V3270(widget),NULL);
128 127
129 - text = v3270_update_selected_text(widget,cut); 128 + if(cut)
  129 + text = lib3270_cut_selected(GTK_V3270(widget)->host);
  130 + else
  131 + text = lib3270_get_selected(GTK_V3270(widget)->host);
130 132
131 if(text) 133 if(text)
132 return g_convert(text, -1, "UTF-8", lib3270_get_display_charset(GTK_V3270(widget)->host), NULL, NULL, NULL); 134 return g_convert(text, -1, "UTF-8", lib3270_get_display_charset(GTK_V3270(widget)->host), NULL, NULL, NULL);
@@ -136,26 +138,13 @@ LIB3270_EXPORT gchar * v3270_get_selected(GtkWidget *widget, gboolean cut) @@ -136,26 +138,13 @@ LIB3270_EXPORT gchar * v3270_get_selected(GtkWidget *widget, gboolean cut)
136 138
137 LIB3270_EXPORT gchar * v3270_get_copy(GtkWidget *widget) 139 LIB3270_EXPORT gchar * v3270_get_copy(GtkWidget *widget)
138 { 140 {
139 - /*  
140 - const char *text;  
141 g_return_val_if_fail(GTK_IS_V3270(widget),NULL); 141 g_return_val_if_fail(GTK_IS_V3270(widget),NULL);
142 -  
143 - text = GTK_V3270(widget)->selection.text;  
144 -  
145 - if(!text)  
146 - text = v3270_update_selected_text(widget,FALSE);  
147 -  
148 - if(text)  
149 - return g_convert(text, -1, "UTF-8", lib3270_get_display_charset(GTK_V3270(widget)->host), NULL, NULL, NULL);  
150 -  
151 - */  
152 -  
153 - return NULL; 142 + return get_copy_as_text(GTK_V3270(widget));
154 } 143 }
155 144
  145 + /*
156 LIB3270_EXPORT void v3270_set_copy(GtkWidget *widget, const gchar *text) 146 LIB3270_EXPORT void v3270_set_copy(GtkWidget *widget, const gchar *text)
157 { 147 {
158 - /*  
159 v3270 * terminal; 148 v3270 * terminal;
160 gchar * isotext; 149 gchar * isotext;
161 150
@@ -187,14 +176,14 @@ LIB3270_EXPORT void v3270_set_copy(GtkWidget *widget, const gchar *text) @@ -187,14 +176,14 @@ LIB3270_EXPORT void v3270_set_copy(GtkWidget *widget, const gchar *text)
187 g_free(isotext); 176 g_free(isotext);
188 177
189 g_signal_emit(widget,v3270_widget_signal[V3270_SIGNAL_CLIPBOARD], 0, TRUE); 178 g_signal_emit(widget,v3270_widget_signal[V3270_SIGNAL_CLIPBOARD], 0, TRUE);
190 - */  
191 } 179 }
  180 + */
192 181
193 void v3270_update_system_clipboard(GtkWidget *widget) 182 void v3270_update_system_clipboard(GtkWidget *widget)
194 { 183 {
195 v3270 * terminal = GTK_V3270(widget); 184 v3270 * terminal = GTK_V3270(widget);
196 185
197 - if(!terminal->selection.bounds.width) 186 + if(!terminal->selection.blocks)
198 { 187 {
199 // No clipboard data, return. 188 // No clipboard data, return.
200 g_signal_emit(widget,v3270_widget_signal[V3270_SIGNAL_CLIPBOARD], 0, FALSE); 189 g_signal_emit(widget,v3270_widget_signal[V3270_SIGNAL_CLIPBOARD], 0, FALSE);
@@ -215,7 +204,6 @@ void v3270_update_system_clipboard(GtkWidget *widget) @@ -215,7 +204,6 @@ void v3270_update_system_clipboard(GtkWidget *widget)
215 gtk_target_list_add_text_targets(list, CLIPBOARD_TYPE_TEXT); 204 gtk_target_list_add_text_targets(list, CLIPBOARD_TYPE_TEXT);
216 targets = gtk_target_table_new_from_list(list, &n_targets); 205 targets = gtk_target_table_new_from_list(list, &n_targets);
217 206
218 -  
219 #ifdef DEBUG 207 #ifdef DEBUG
220 { 208 {
221 int ix; 209 int ix;
@@ -244,16 +232,6 @@ void v3270_update_system_clipboard(GtkWidget *widget) @@ -244,16 +232,6 @@ void v3270_update_system_clipboard(GtkWidget *widget)
244 232
245 } 233 }
246 234
247 -LIB3270_EXPORT void v3270_copy_text(GtkWidget *widget, V3270_SELECT_FORMAT mode, gboolean cut)  
248 -{  
249 - /*  
250 - g_return_if_fail(GTK_IS_V3270(widget));  
251 - GTK_V3270(widget)->selection.format = mode;  
252 - v3270_update_selected_text(widget,cut);  
253 - v3270_update_system_clipboard(widget);  
254 - */  
255 -}  
256 -  
257 LIB3270_EXPORT void v3270_unselect(GtkWidget *widget) 235 LIB3270_EXPORT void v3270_unselect(GtkWidget *widget)
258 { 236 {
259 v3270_disable_updates(widget); 237 v3270_disable_updates(widget);
src/clipboard/text.c
@@ -30,42 +30,6 @@ @@ -30,42 +30,6 @@
30 #include <clipboard.h> 30 #include <clipboard.h>
31 31
32 32
33 -LIB3270_EXPORT void v3270_copy_text_append(GtkWidget *widget)  
34 -{  
35 - /*  
36 - v3270 * terminal;  
37 - char * str;  
38 -  
39 - g_return_if_fail(GTK_IS_V3270(widget));  
40 -  
41 - terminal = GTK_V3270(widget);  
42 -  
43 - if(!terminal->selection.text)  
44 - {  
45 - // Clipboard is empty, do a single copy  
46 - v3270_copy_text(widget, V3270_SELECT_TEXT, FALSE);  
47 - return;  
48 - }  
49 -  
50 - str = lib3270_get_selected(terminal->host);  
51 -  
52 - if(str)  
53 - {  
54 - size_t len = strlen(terminal->selection.text)+strlen(str)+2;  
55 -  
56 - terminal->selection.text = lib3270_realloc(terminal->selection.text,len);  
57 -  
58 - strncat(terminal->selection.text,"\n",len);  
59 - strncat(terminal->selection.text,str,len);  
60 -  
61 - lib3270_free(str);  
62 - }  
63 -  
64 - v3270_update_system_clipboard(widget);  
65 - */  
66 -  
67 -}  
68 -  
69 const char * v3270_update_selected_text(GtkWidget *widget, gboolean cut) 33 const char * v3270_update_selected_text(GtkWidget *widget, gboolean cut)
70 { 34 {
71 /* 35 /*
src/include/clipboard.h
@@ -45,6 +45,20 @@ @@ -45,6 +45,20 @@
45 CLIPBOARD_TYPE_TEXT, 45 CLIPBOARD_TYPE_TEXT,
46 }; 46 };
47 47
  48 + struct selection
  49 + {
  50 + struct {
  51 + unsigned int row;
  52 + unsigned int col;
  53 + unsigned int width;
  54 + unsigned int height;
  55 +
  56 + } bounds; ///< @brief Clipboard rectangle.
  57 +
  58 + struct v3270_character contents[1];
  59 +
  60 + };
  61 +
48 G_GNUC_INTERNAL void v3270_update_system_clipboard(GtkWidget *widget); 62 G_GNUC_INTERNAL void v3270_update_system_clipboard(GtkWidget *widget);
49 G_GNUC_INTERNAL const char * v3270_update_selected_text(GtkWidget *widget, gboolean cut); 63 G_GNUC_INTERNAL const char * v3270_update_selected_text(GtkWidget *widget, gboolean cut);
50 64
src/include/terminal.h
@@ -117,29 +117,12 @@ G_BEGIN_DECLS @@ -117,29 +117,12 @@ G_BEGIN_DECLS
117 117
118 struct { 118 struct {
119 119
120 - int baddr; ///< @brief Selection address.  
121 - V3270_SELECT_FORMAT format; ///< @brief Copy format. 120 + int baddr; ///< @brief Selection address.
  121 + V3270_SELECT_FORMAT format; ///< @brief Copy format.
122 122
123 - struct {  
124 - unsigned int row;  
125 - unsigned int col;  
126 - unsigned int width;  
127 - unsigned int height; 123 + GList * blocks; ///< @brief Selection blocks.
128 124
129 - } bounds; ///< @brief Clipboard rectangle.  
130 -  
131 - struct v3270_character * contents;  
132 -  
133 - } selection;  
134 -  
135 - /*  
136 - struct  
137 - {  
138 - V3270_SELECT_FORMAT format; ///< Copy format  
139 - char * text; ///< Clipboard contents (lib3270 charset)  
140 - int baddr; ///< Selection addr  
141 } selection; 125 } selection;
142 - */  
143 126
144 LIB3270_POINTER pointer_id; 127 LIB3270_POINTER pointer_id;
145 unsigned char pointer; /**< Mouse pointer ID */ 128 unsigned char pointer; /**< Mouse pointer ID */
src/include/v3270.h
@@ -192,7 +192,7 @@ @@ -192,7 +192,7 @@
192 192
193 LIB3270_EXPORT gchar * v3270_get_selected(GtkWidget *widget, gboolean cut); 193 LIB3270_EXPORT gchar * v3270_get_selected(GtkWidget *widget, gboolean cut);
194 LIB3270_EXPORT gchar * v3270_get_copy(GtkWidget *widget); 194 LIB3270_EXPORT gchar * v3270_get_copy(GtkWidget *widget);
195 - LIB3270_EXPORT void v3270_set_copy(GtkWidget *widget, const gchar *text); 195 +// LIB3270_EXPORT void v3270_set_copy(GtkWidget *widget, const gchar *text);
196 196
197 LIB3270_EXPORT gchar * v3270_get_text(GtkWidget *widget,int offset, int len); 197 LIB3270_EXPORT gchar * v3270_get_text(GtkWidget *widget,int offset, int len);
198 LIB3270_EXPORT gchar * v3270_get_region(GtkWidget *widget, gint start_pos, gint end_pos, gboolean all); 198 LIB3270_EXPORT gchar * v3270_get_region(GtkWidget *widget, gint start_pos, gint end_pos, gboolean all);
@@ -208,8 +208,9 @@ @@ -208,8 +208,9 @@
208 LIB3270_EXPORT void v3270_select_region(GtkWidget *widget, gint start, gint end); 208 LIB3270_EXPORT void v3270_select_region(GtkWidget *widget, gint start, gint end);
209 209
210 LIB3270_EXPORT void v3270_copy(GtkWidget *widget, V3270_SELECT_FORMAT mode, gboolean cut); 210 LIB3270_EXPORT void v3270_copy(GtkWidget *widget, V3270_SELECT_FORMAT mode, gboolean cut);
211 - LIB3270_EXPORT void v3270_copy_text(GtkWidget *widget, V3270_SELECT_FORMAT mode, gboolean cut);  
212 - LIB3270_EXPORT void v3270_copy_text_append(GtkWidget *widget); 211 +
  212 + LIB3270_EXPORT void v3270_copy_selection(GtkWidget *widget, V3270_SELECT_FORMAT mode, gboolean cut);
  213 + LIB3270_EXPORT void v3270_append_selection(GtkWidget *widget, gboolean cut);
213 214
214 LIB3270_EXPORT void v3270_paste(GtkWidget *widget); 215 LIB3270_EXPORT void v3270_paste(GtkWidget *widget);
215 LIB3270_EXPORT void v3270_paste_text(GtkWidget *widget, const gchar *text, const gchar *encoding); 216 LIB3270_EXPORT void v3270_paste_text(GtkWidget *widget, const gchar *text, const gchar *encoding);
src/trace/exec.c
@@ -183,11 +183,11 @@ @@ -183,11 +183,11 @@
183 if(!(*arg && g_ascii_strcasecmp(arg,"text"))) 183 if(!(*arg && g_ascii_strcasecmp(arg,"text")))
184 { 184 {
185 // No argument or "text" copy text. 185 // No argument or "text" copy text.
186 - v3270_copy(widget, V3270_SELECT_TEXT, FALSE); 186 + v3270_copy_selection(widget, V3270_SELECT_TEXT, FALSE);
187 } 187 }
188 else if(!g_ascii_strcasecmp(arg,"table")) 188 else if(!g_ascii_strcasecmp(arg,"table"))
189 { 189 {
190 - v3270_copy(widget, V3270_SELECT_TABLE, FALSE); 190 + v3270_copy_selection(widget, V3270_SELECT_TABLE, FALSE);
191 } 191 }
192 192
193 return 0; 193 return 0;