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 30 #include <clipboard.h>
31 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 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 42 return;
49 43  
50 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 57 // Copy terminal buffer
57 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 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 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 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 68 gdk_display_beep(gdk_display_get_default());
70 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 76 pos++;
78 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 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 44 }
45 45  
46 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 74 return g_convert(text, -1, "UTF-8", lib3270_get_display_charset(terminal->host), NULL, NULL, NULL);
  75 +
67 76 }
68 77  
69 78 static void clipboard_get(G_GNUC_UNUSED GtkClipboard *clipboard, GtkSelectionData *selection, guint target, GObject *obj)
70 79 {
71 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 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 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 104 */
102 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 121 */
123 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 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 133 if(text)
132 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 138  
137 139 LIB3270_EXPORT gchar * v3270_get_copy(GtkWidget *widget)
138 140 {
139   - /*
140   - const char *text;
141 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 146 LIB3270_EXPORT void v3270_set_copy(GtkWidget *widget, const gchar *text)
157 147 {
158   - /*
159 148 v3270 * terminal;
160 149 gchar * isotext;
161 150  
... ... @@ -187,14 +176,14 @@ LIB3270_EXPORT void v3270_set_copy(GtkWidget *widget, const gchar *text)
187 176 g_free(isotext);
188 177  
189 178 g_signal_emit(widget,v3270_widget_signal[V3270_SIGNAL_CLIPBOARD], 0, TRUE);
190   - */
191 179 }
  180 + */
192 181  
193 182 void v3270_update_system_clipboard(GtkWidget *widget)
194 183 {
195 184 v3270 * terminal = GTK_V3270(widget);
196 185  
197   - if(!terminal->selection.bounds.width)
  186 + if(!terminal->selection.blocks)
198 187 {
199 188 // No clipboard data, return.
200 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 204 gtk_target_list_add_text_targets(list, CLIPBOARD_TYPE_TEXT);
216 205 targets = gtk_target_table_new_from_list(list, &n_targets);
217 206  
218   -
219 207 #ifdef DEBUG
220 208 {
221 209 int ix;
... ... @@ -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 235 LIB3270_EXPORT void v3270_unselect(GtkWidget *widget)
258 236 {
259 237 v3270_disable_updates(widget);
... ...
src/clipboard/text.c
... ... @@ -30,42 +30,6 @@
30 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 33 const char * v3270_update_selected_text(GtkWidget *widget, gboolean cut)
70 34 {
71 35 /*
... ...
src/include/clipboard.h
... ... @@ -45,6 +45,20 @@
45 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 62 G_GNUC_INTERNAL void v3270_update_system_clipboard(GtkWidget *widget);
49 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 117  
118 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 125 } selection;
142   - */
143 126  
144 127 LIB3270_POINTER pointer_id;
145 128 unsigned char pointer; /**< Mouse pointer ID */
... ...
src/include/v3270.h
... ... @@ -192,7 +192,7 @@
192 192  
193 193 LIB3270_EXPORT gchar * v3270_get_selected(GtkWidget *widget, gboolean cut);
194 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 197 LIB3270_EXPORT gchar * v3270_get_text(GtkWidget *widget,int offset, int len);
198 198 LIB3270_EXPORT gchar * v3270_get_region(GtkWidget *widget, gint start_pos, gint end_pos, gboolean all);
... ... @@ -208,8 +208,9 @@
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   - 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 215 LIB3270_EXPORT void v3270_paste(GtkWidget *widget);
215 216 LIB3270_EXPORT void v3270_paste_text(GtkWidget *widget, const gchar *text, const gchar *encoding);
... ...
src/trace/exec.c
... ... @@ -183,11 +183,11 @@
183 183 if(!(*arg && g_ascii_strcasecmp(arg,"text")))
184 184 {
185 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 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 193 return 0;
... ...