diff --git a/Makefile.in b/Makefile.in index e2a9edb..88e6f8c 100644 --- a/Makefile.in +++ b/Makefile.in @@ -33,6 +33,8 @@ SOURCES= \ $(wildcard src/terminal/@OSNAME@/*.rc) \ $(wildcard src/terminal/@OSNAME@/*.c) \ $(wildcard src/filetransfer/*.c) \ + $(wildcard src/clipboard/*.c) \ + $(wildcard src/clipboard/@OSNAME@/*.c) \ $(wildcard src/trace/*.c) \ $(wildcard src/dialogs/*.c) \ $(wildcard src/dialogs/@OSNAME@/*.c) \ diff --git a/src/clipboard/linux/paste.c b/src/clipboard/linux/paste.c new file mode 100644 index 0000000..24e2f44 --- /dev/null +++ b/src/clipboard/linux/paste.c @@ -0,0 +1,43 @@ +/* + * "Software pw3270, desenvolvido com base nos códigos fontes do WC3270 e X3270 + * (Paul Mattes Paul.Mattes@usa.net), de emulação de terminal 3270 para acesso a + * aplicativos mainframe. Registro no INPI sob o nome G3270. + * + * Copyright (C) <2008> + * + * Este programa é software livre. Você pode redistribuí-lo e/ou modificá-lo sob + * os termos da GPL v.2 - Licença Pública Geral GNU, conforme publicado pela + * Free Software Foundation. + * + * Este programa é distribuído na expectativa de ser útil, mas SEM QUALQUER + * GARANTIA; sem mesmo a garantia implícita de COMERCIALIZAÇÃO ou de ADEQUAÇÃO + * A QUALQUER PROPÓSITO EM PARTICULAR. Consulte a Licença Pública Geral GNU para + * obter mais detalhes. + * + * Você deve ter recebido uma cópia da Licença Pública Geral GNU junto com este + * programa; se não, escreva para a Free Software Foundation, Inc., 51 Franklin + * St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Este programa está nomeado como selection.c e possui - linhas de código. + * + * Contatos: + * + * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck) + * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça) + * + */ + + #include + +/*--[ Implement ]------------------------------------------------------------------------------------*/ + +static void text_received(G_GNUC_UNUSED GtkClipboard *clipboard, const gchar *text, GtkWidget *widget) +{ + v3270_paste_string(widget,text,"UTF-8"); +} + +LIB3270_EXPORT void v3270_paste(GtkWidget *widget) +{ + gtk_clipboard_request_text(gtk_widget_get_clipboard(widget,GDK_SELECTION_CLIPBOARD),(GtkClipboardTextReceivedFunc) text_received,(gpointer) widget); +} + diff --git a/src/clipboard/selection.c b/src/clipboard/selection.c new file mode 100644 index 0000000..f1fe0cf --- /dev/null +++ b/src/clipboard/selection.c @@ -0,0 +1,211 @@ +/* + * "Software pw3270, desenvolvido com base nos códigos fontes do WC3270 e X3270 + * (Paul Mattes Paul.Mattes@usa.net), de emulação de terminal 3270 para acesso a + * aplicativos mainframe. Registro no INPI sob o nome G3270. + * + * Copyright (C) <2008> + * + * Este programa é software livre. Você pode redistribuí-lo e/ou modificá-lo sob + * os termos da GPL v.2 - Licença Pública Geral GNU, conforme publicado pela + * Free Software Foundation. + * + * Este programa é distribuído na expectativa de ser útil, mas SEM QUALQUER + * GARANTIA; sem mesmo a garantia implícita de COMERCIALIZAÇÃO ou de ADEQUAÇÃO + * A QUALQUER PROPÓSITO EM PARTICULAR. Consulte a Licença Pública Geral GNU para + * obter mais detalhes. + * + * Você deve ter recebido uma cópia da Licença Pública Geral GNU junto com este + * programa; se não, escreva para a Free Software Foundation, Inc., 51 Franklin + * St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Este programa está nomeado como selection.c e possui - linhas de código. + * + * Contatos: + * + * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck) + * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça) + * + */ + + #include + +/*--[ Globals ]--------------------------------------------------------------------------------------*/ + + static const GtkTargetEntry targets[] = + { + { "COMPOUND_TEXT", 0, CLIPBOARD_TYPE_TEXT }, + { "UTF8_STRING", 0, CLIPBOARD_TYPE_TEXT }, + }; + +/*--[ Implement ]------------------------------------------------------------------------------------*/ + +static void clipboard_clear(G_GNUC_UNUSED GtkClipboard *clipboard, G_GNUC_UNUSED GObject *obj) +{ +} + +static void clipboard_get(G_GNUC_UNUSED GtkClipboard *clipboard, GtkSelectionData *selection, guint target, GObject *obj) +{ + v3270 * widget = GTK_V3270(obj); + + switch(target) + { + case CLIPBOARD_TYPE_TEXT: /* Get clipboard contents as text */ + if(!widget->selection.text) + { + lib3270_ring_bell(widget->host); + } + else + { + gchar * text = g_convert(widget->selection.text, -1, "UTF-8", lib3270_get_display_charset(widget->host), NULL, NULL, NULL); + gtk_selection_data_set_text(selection,text,-1); + g_free(text); + } + break; + + default: + g_warning("Unexpected clipboard type %d\n",target); + } +} + +/** + * Clear clipboard contents. + * + * @param terminal Pointer to the terminal Widget. + * + */ +void v3270_clear_clipboard(v3270 *terminal) +{ + terminal->selection.text = lib3270_free(terminal->selection.text); +} + +/** + * Get lib3270 selection as a g_malloc buffer. + * + * @param widget Widget containing the desired section. + * + * @return NULL if error, otherwise the selected buffer contents (release with g_free). + * + */ +LIB3270_EXPORT gchar * v3270_get_selected(GtkWidget *widget, gboolean cut) +{ + const char *text; + + g_return_val_if_fail(GTK_IS_V3270(widget),NULL); + + text = v3270_update_selected_text(widget,cut); + + if(text) + return g_convert(text, -1, "UTF-8", lib3270_get_display_charset(GTK_V3270(widget)->host), NULL, NULL, NULL); + + return NULL; +} + +LIB3270_EXPORT gchar * v3270_get_copy(GtkWidget *widget) +{ + const char *text; + g_return_val_if_fail(GTK_IS_V3270(widget),NULL); + + text = GTK_V3270(widget)->selection.text; + + if(!text) + text = v3270_update_selected_text(widget,FALSE); + + if(text) + return g_convert(text, -1, "UTF-8", lib3270_get_display_charset(GTK_V3270(widget)->host), NULL, NULL, NULL); + + return NULL; +} + +LIB3270_EXPORT void v3270_set_copy(GtkWidget *widget, const gchar *text) +{ + v3270 * terminal; + gchar * isotext; + + g_return_if_fail(GTK_IS_V3270(widget)); + + terminal = GTK_V3270(widget); + v3270_clear_clipboard(terminal); + + if(!text) + { + /* No string, signal clipboard clear and return */ + g_signal_emit(widget,v3270_widget_signal[V3270_SIGNAL_CLIPBOARD], 0, FALSE); + return; + } + + /* Received text, replace the selection buffer */ + terminal->selection.format = V3270_SELECT_TEXT; + isotext = g_convert(text, -1, lib3270_get_display_charset(terminal->host), "UTF-8", NULL, NULL, NULL); + + if(!isotext) + { + /* No string, signal clipboard clear and return */ + g_signal_emit(widget,v3270_widget_signal[V3270_SIGNAL_CLIPBOARD], 0, FALSE); + return; + } + + terminal->selection.text = lib3270_strdup(isotext); + + g_free(isotext); + + g_signal_emit(widget,v3270_widget_signal[V3270_SIGNAL_CLIPBOARD], 0, TRUE); +} + +void v3270_update_system_clipboard(GtkWidget *widget) +{ + if(GTK_V3270(widget)->selection.text) + { + GtkClipboard * clipboard = gtk_widget_get_clipboard(widget,GDK_SELECTION_CLIPBOARD); + + if(gtk_clipboard_set_with_owner( + clipboard, + targets, + G_N_ELEMENTS(targets), + (GtkClipboardGetFunc) clipboard_get, + (GtkClipboardClearFunc) clipboard_clear, + G_OBJECT(widget) + )) + { + gtk_clipboard_set_can_store(clipboard,targets,1); + } + + g_signal_emit(widget,v3270_widget_signal[V3270_SIGNAL_CLIPBOARD], 0, TRUE); + } +} + +LIB3270_EXPORT void v3270_copy(GtkWidget *widget, V3270_SELECT_FORMAT mode, gboolean cut) +{ + g_return_if_fail(GTK_IS_V3270(widget)); + GTK_V3270(widget)->selection.format = mode; + v3270_update_selected_text(widget,cut); + v3270_update_system_clipboard(widget); +} + +LIB3270_EXPORT void v3270_unselect(GtkWidget *widget) +{ + v3270_disable_updates(widget); + lib3270_unselect(v3270_get_session(widget)); + v3270_enable_updates(widget); +} + +gboolean v3270_get_selection_bounds(GtkWidget *widget, gint *start, gint *end) +{ + g_return_val_if_fail(GTK_IS_V3270(widget),FALSE); + return lib3270_get_selection_bounds(GTK_V3270(widget)->host,start,end) == 0 ? FALSE : TRUE; +} + +LIB3270_EXPORT void v3270_select_region(GtkWidget *widget, gint start, gint end) +{ + g_return_if_fail(GTK_IS_V3270(widget)); + lib3270_select_region(GTK_V3270(widget)->host,start,end); +} + +LIB3270_EXPORT void v3270_select_all(GtkWidget *widget) +{ + g_return_if_fail(GTK_IS_V3270(widget)); + v3270_disable_updates(widget); + lib3270_select_all(v3270_get_session(widget)); + v3270_enable_updates(widget); +} + + diff --git a/src/clipboard/text.c b/src/clipboard/text.c new file mode 100644 index 0000000..322822a --- /dev/null +++ b/src/clipboard/text.c @@ -0,0 +1,286 @@ +/* + * "Software pw3270, desenvolvido com base nos códigos fontes do WC3270 e X3270 + * (Paul Mattes Paul.Mattes@usa.net), de emulação de terminal 3270 para acesso a + * aplicativos mainframe. Registro no INPI sob o nome G3270. + * + * Copyright (C) <2008> + * + * Este programa é software livre. Você pode redistribuí-lo e/ou modificá-lo sob + * os termos da GPL v.2 - Licença Pública Geral GNU, conforme publicado pela + * Free Software Foundation. + * + * Este programa é distribuído na expectativa de ser útil, mas SEM QUALQUER + * GARANTIA; sem mesmo a garantia implícita de COMERCIALIZAÇÃO ou de ADEQUAÇÃO + * A QUALQUER PROPÓSITO EM PARTICULAR. Consulte a Licença Pública Geral GNU para + * obter mais detalhes. + * + * Você deve ter recebido uma cópia da Licença Pública Geral GNU junto com este + * programa; se não, escreva para a Free Software Foundation, Inc., 51 Franklin + * St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Este programa está nomeado como - e possui - linhas de código. + * + * Contatos: + * + * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck) + * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça) + * + */ + + #include + + +LIB3270_EXPORT void v3270_copy_append(GtkWidget *widget) +{ + v3270 * terminal; + char * str; + + g_return_if_fail(GTK_IS_V3270(widget)); + + terminal = GTK_V3270(widget); + + if(!terminal->selection.text) + { + // Clipboard is empty, do a single copy + v3270_copy(widget, V3270_SELECT_TEXT, FALSE); + return; + } + + str = lib3270_get_selected(terminal->host); + + if(str) + { + size_t len = strlen(terminal->selection.text)+strlen(str)+2; + + terminal->selection.text = lib3270_realloc(terminal->selection.text,len); + + strncat(terminal->selection.text,"\n",len); + strncat(terminal->selection.text,str,len); + + lib3270_free(str); + } + + v3270_update_system_clipboard(widget); + +} + +const char * v3270_update_selected_text(GtkWidget *widget, gboolean cut) +{ + char * text; + v3270 * terminal = GTK_V3270(widget); + + v3270_clear_clipboard(terminal); + + if(cut) + text = lib3270_cut_selected(terminal->host); + else + text = lib3270_get_selected(terminal->host); + + if(!text) + { + g_signal_emit(widget,v3270_widget_signal[V3270_SIGNAL_CLIPBOARD], 0, FALSE); + lib3270_ring_bell(terminal->host); + return NULL; + } + + if(terminal->selection.format == V3270_SELECT_TABLE) + { + // Convert text to table + gchar **ln = g_strsplit(text,"\n",-1); + int width = lib3270_get_width(terminal->host); + gboolean cols[width]; + int l; + GString * buffer; + + memset(cols,0,sizeof(gboolean)*width); + + // Find column delimiters + for(l=0;ln[l];l++) + { + int c; + gchar * ptr = ln[l]; + + for(c=0;cselection.text = text; + +} + +LIB3270_EXPORT void v3270_paste_string(GtkWidget *widget, const gchar *text, const gchar *encoding) +{ + gchar * buffer = NULL; + H3270 * session = v3270_get_session(widget); + const gchar * charset = lib3270_get_display_charset(session); + gboolean next; + + if(!text) + return; + else if(g_ascii_strcasecmp(encoding,charset)) + buffer = g_convert(text, -1, charset, encoding, NULL, NULL, NULL); + else + buffer = g_strdup(text); + + if(!buffer) + { + /* Conversion failed, update special chars and try again */ + size_t f; + + static const struct _xlat + { + const gchar *from; + const gchar *to; + } xlat[] = + { + { "–", "-" }, + { "→", "->" }, + { "←", "<-" }, + { "©", "(c)" }, + { "↔", "<->" }, + { "™", "(TM)" }, + { "®", "(R)" }, + { "“", "\"" }, + { "”", "\"" }, + { "…", "..." }, + { "•", "*" }, + { "․", "." }, + { "·", "*" }, + + }; + + gchar *string = g_strdup(text); + + // FIXME (perry#1#): Is there any better way for a "sed" here? + for(f=0;fmessage, ln[f]); + + gtk_dialog_run(GTK_DIALOG (dialog)); + gtk_widget_destroy(dialog); + + break; + } + else + { + g_free(str); + } + + } + g_strfreev(ln); + + } + + g_free(string); + } + + if(buffer) + { + /* Remove TABS */ + gchar *ptr; + + for(ptr = buffer;*ptr;ptr++) + { + if(*ptr == '\t') + *ptr = ' '; + } + } + else + { + g_signal_emit(widget,v3270_widget_signal[V3270_SIGNAL_PASTENEXT], 0, FALSE); + return; + } + + next = lib3270_paste(session,(unsigned char *) buffer) ? TRUE : FALSE; + + g_free(buffer); + + g_signal_emit(widget,v3270_widget_signal[V3270_SIGNAL_PASTENEXT], 0, next); + +} diff --git a/src/clipboard/windows/paste.c b/src/clipboard/windows/paste.c new file mode 100644 index 0000000..08dde4a --- /dev/null +++ b/src/clipboard/windows/paste.c @@ -0,0 +1,58 @@ +/* + * "Software pw3270, desenvolvido com base nos códigos fontes do WC3270 e X3270 + * (Paul Mattes Paul.Mattes@usa.net), de emulação de terminal 3270 para acesso a + * aplicativos mainframe. Registro no INPI sob o nome G3270. + * + * Copyright (C) <2008> + * + * Este programa é software livre. Você pode redistribuí-lo e/ou modificá-lo sob + * os termos da GPL v.2 - Licença Pública Geral GNU, conforme publicado pela + * Free Software Foundation. + * + * Este programa é distribuído na expectativa de ser útil, mas SEM QUALQUER + * GARANTIA; sem mesmo a garantia implícita de COMERCIALIZAÇÃO ou de ADEQUAÇÃO + * A QUALQUER PROPÓSITO EM PARTICULAR. Consulte a Licença Pública Geral GNU para + * obter mais detalhes. + * + * Você deve ter recebido uma cópia da Licença Pública Geral GNU junto com este + * programa; se não, escreva para a Free Software Foundation, Inc., 51 Franklin + * St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Este programa está nomeado como selection.c e possui - linhas de código. + * + * Contatos: + * + * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck) + * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça) + * + */ + + #include + #include + +/*--[ Implement ]------------------------------------------------------------------------------------*/ + +LIB3270_EXPORT void v3270_paste(GtkWidget *widget) +{ + HGLOBAL hglb; + + if (!IsClipboardFormatAvailable(CF_TEXT)) + return; + + if (!OpenClipboard(NULL)) + return; + + hglb = GetClipboardData(CF_TEXT); + if (hglb != NULL) + { + LPTSTR lptstr = GlobalLock(hglb); + if (lptstr != NULL) + { + v3270_paste_string(widget,lptstr,"CP1252"); + GlobalUnlock(hglb); + } + } + + CloseClipboard(); + +} diff --git a/src/include/clipboard.h b/src/include/clipboard.h new file mode 100644 index 0000000..69bdda4 --- /dev/null +++ b/src/include/clipboard.h @@ -0,0 +1,54 @@ +/* + * "Software pw3270, desenvolvido com base nos códigos fontes do WC3270 e X3270 + * (Paul Mattes Paul.Mattes@usa.net), de emulação de terminal 3270 para acesso a + * aplicativos mainframe. Registro no INPI sob o nome G3270. + * + * Copyright (C) <2008> + * + * Este programa é software livre. Você pode redistribuí-lo e/ou modificá-lo sob + * os termos da GPL v.2 - Licença Pública Geral GNU, conforme publicado pela + * Free Software Foundation. + * + * Este programa é distribuído na expectativa de ser útil, mas SEM QUALQUER + * GARANTIA; sem mesmo a garantia implícita de COMERCIALIZAÇÃO ou de ADEQUAÇÃO + * A QUALQUER PROPÓSITO EM PARTICULAR. Consulte a Licença Pública Geral GNU para + * obter mais detalhes. + * + * Você deve ter recebido uma cópia da Licença Pública Geral GNU junto com este + * programa; se não, escreva para a Free Software Foundation, Inc., 51 Franklin + * St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Este programa está nomeado como clipboard.h e possui - linhas de código. + * + * Contatos: + * + * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck) + * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça) + * + */ + +#ifndef V3270_CLIPBOARD_H_INCLUDED + + #define V3270_CLIPBOARD_H_INCLUDED + + #include + #include + #include + #include + #include + #include + #include + #include + + enum + { + CLIPBOARD_TYPE_TEXT, + }; + + G_GNUC_INTERNAL void v3270_update_system_clipboard(GtkWidget *widget); + G_GNUC_INTERNAL const char * v3270_update_selected_text(GtkWidget *widget, gboolean cut); + + + +#endif // V3270_CLIPBOARD_H_INCLUDED + diff --git a/src/include/terminal.h b/src/include/terminal.h index 3000d02..0759344 100644 --- a/src/include/terminal.h +++ b/src/include/terminal.h @@ -101,7 +101,6 @@ G_BEGIN_DECLS int selecting : 1; /**< Selecting region */ int moving : 1; /**< Moving selected region */ int resizing : 1; /**< Resizing selected region */ - int table : 1; /**< Copy mode is table */ int scaled_fonts : 1; /**< Use scaled fonts */ int drawing : 1; /**< Draw widget? */ @@ -118,8 +117,9 @@ G_BEGIN_DECLS struct { - char * text; /**< Clipboard contents (lib3270 charset) */ - int baddr; /**< Selection addr */ + V3270_SELECT_FORMAT format; /**< Copy format */ + char * text; /**< Clipboard contents (lib3270 charset) */ + int baddr; /**< Selection addr */ } selection; LIB3270_POINTER pointer_id; diff --git a/src/terminal/get.c b/src/terminal/get.c new file mode 100644 index 0000000..7c3bc89 --- /dev/null +++ b/src/terminal/get.c @@ -0,0 +1,81 @@ +/* + * "Software pw3270, desenvolvido com base nos códigos fontes do WC3270 e X3270 + * (Paul Mattes Paul.Mattes@usa.net), de emulação de terminal 3270 para acesso a + * aplicativos mainframe. Registro no INPI sob o nome G3270. + * + * Copyright (C) <2008> + * + * Este programa é software livre. Você pode redistribuí-lo e/ou modificá-lo sob + * os termos da GPL v.2 - Licença Pública Geral GNU, conforme publicado pela + * Free Software Foundation. + * + * Este programa é distribuído na expectativa de ser útil, mas SEM QUALQUER + * GARANTIA; sem mesmo a garantia implícita de COMERCIALIZAÇÃO ou de ADEQUAÇÃO + * A QUALQUER PROPÓSITO EM PARTICULAR. Consulte a Licença Pública Geral GNU para + * obter mais detalhes. + * + * Você deve ter recebido uma cópia da Licença Pública Geral GNU junto com este + * programa; se não, escreva para a Free Software Foundation, Inc., 51 Franklin + * St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Este programa está nomeado como - e possui - linhas de código. + * + * Contatos: + * + * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck) + * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça) + * + */ + + #include + #include + #include + +/*--[ Implement ]------------------------------------------------------------------------------------*/ + +/** + * Get text at informed area. + * + * @param widget Widget. + * @param offset Offset of the desired text. + * @param len Number of characters to get. + * + */ +LIB3270_EXPORT gchar * v3270_get_text(GtkWidget *widget, int offset, int len) +{ + v3270 * terminal; + gchar * text; + char * str; + + g_return_val_if_fail(GTK_IS_V3270(widget),NULL); + + terminal = GTK_V3270(widget); + + str = lib3270_get_string_at_address(terminal->host, offset, len, '\n'); + + if(!str) + return NULL; + + text = g_convert(str, -1, "UTF-8", lib3270_get_display_charset(terminal->host), NULL, NULL, NULL); + + lib3270_free(str); + return text; +} + +gchar * v3270_get_region(GtkWidget *widget, gint start_pos, gint end_pos, gboolean all) +{ + char * str; + gchar * utftext; + + g_return_val_if_fail(GTK_IS_V3270(widget),NULL); + + str = lib3270_get_region(GTK_V3270(widget)->host,start_pos,end_pos,all); + if(!str) + return NULL; + + utftext = g_convert(str, -1, "UTF-8", lib3270_get_display_charset(GTK_V3270(widget)->host), NULL, NULL, NULL); + + lib3270_free(str); + + return utftext; +} diff --git a/src/terminal/selection.c b/src/terminal/selection.c deleted file mode 100644 index 407dcc5..0000000 --- a/src/terminal/selection.c +++ /dev/null @@ -1,566 +0,0 @@ -/* - * "Software pw3270, desenvolvido com base nos códigos fontes do WC3270 e X3270 - * (Paul Mattes Paul.Mattes@usa.net), de emulação de terminal 3270 para acesso a - * aplicativos mainframe. Registro no INPI sob o nome G3270. - * - * Copyright (C) <2008> - * - * Este programa é software livre. Você pode redistribuí-lo e/ou modificá-lo sob - * os termos da GPL v.2 - Licença Pública Geral GNU, conforme publicado pela - * Free Software Foundation. - * - * Este programa é distribuído na expectativa de ser útil, mas SEM QUALQUER - * GARANTIA; sem mesmo a garantia implícita de COMERCIALIZAÇÃO ou de ADEQUAÇÃO - * A QUALQUER PROPÓSITO EM PARTICULAR. Consulte a Licença Pública Geral GNU para - * obter mais detalhes. - * - * Você deve ter recebido uma cópia da Licença Pública Geral GNU junto com este - * programa; se não, escreva para a Free Software Foundation, Inc., 51 Franklin - * St, Fifth Floor, Boston, MA 02110-1301 USA - * - * Este programa está nomeado como selection.c e possui - linhas de código. - * - * Contatos: - * - * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck) - * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça) - * - */ - - #include - #include - #include - #include - #include - #include - #include - #include - -/*--[ Globals ]--------------------------------------------------------------------------------------*/ - - enum - { - CLIPBOARD_TYPE_TEXT, - }; - - static const GtkTargetEntry targets[] = - { - { "COMPOUND_TEXT", 0, CLIPBOARD_TYPE_TEXT }, - { "UTF8_STRING", 0, CLIPBOARD_TYPE_TEXT }, - }; - -/*--[ Implement ]------------------------------------------------------------------------------------*/ - -static void clipboard_clear(G_GNUC_UNUSED GtkClipboard *clipboard, G_GNUC_UNUSED GObject *obj) -{ -} - -static void clipboard_get(G_GNUC_UNUSED GtkClipboard *clipboard, GtkSelectionData *selection, guint target, GObject *obj) -{ - v3270 * widget = GTK_V3270(obj); - - switch(target) - { - case CLIPBOARD_TYPE_TEXT: /* Get clipboard contents as text */ - if(!widget->selection.text) - { - lib3270_ring_bell(widget->host); - } - else - { - gchar * text = g_convert(widget->selection.text, -1, "UTF-8", lib3270_get_display_charset(widget->host), NULL, NULL, NULL); - gtk_selection_data_set_text(selection,text,-1); - g_free(text); - } - break; - - default: - g_warning("Unexpected clipboard type %d\n",target); - } -} - -/** - * Clear clipboard contents. - * - * @param terminal Pointer to the terminal Widget. - * - */ -void v3270_clear_clipboard(v3270 *terminal) -{ - terminal->selection.text = lib3270_free(terminal->selection.text); -} - -/** - * Get text at informed area. - * - * @param widget Widget. - * @param offset Offset of the desired text. - * @param len Number of characters to get. - * - */ -LIB3270_EXPORT gchar * v3270_get_text(GtkWidget *widget, int offset, int len) -{ - v3270 * terminal; - gchar * text; - char * str; - - g_return_val_if_fail(GTK_IS_V3270(widget),NULL); - - terminal = GTK_V3270(widget); - - str = lib3270_get_string_at_address(terminal->host, offset, len, '\n'); - - if(!str) - return NULL; - - text = g_convert(str, -1, "UTF-8", lib3270_get_display_charset(terminal->host), NULL, NULL, NULL); - - lib3270_free(str); - return text; -} - -static const char * update_selected_text(GtkWidget *widget, gboolean cut) -{ - char * text; - v3270 * terminal = GTK_V3270(widget); - - v3270_clear_clipboard(terminal); - - if(cut) - text = lib3270_cut_selected(terminal->host); - else - text = lib3270_get_selected(terminal->host); - - if(!text) - { - g_signal_emit(widget,v3270_widget_signal[V3270_SIGNAL_CLIPBOARD], 0, FALSE); - lib3270_ring_bell(terminal->host); - return NULL; - } - - if(terminal->table) - { - // Convert text to table - gchar **ln = g_strsplit(text,"\n",-1); - int width = lib3270_get_width(terminal->host); - gboolean cols[width]; - int l; - GString * buffer; - - memset(cols,0,sizeof(gboolean)*width); - - // Find column delimiters - for(l=0;ln[l];l++) - { - int c; - gchar * ptr = ln[l]; - - for(c=0;cselection.text = text; - -} - -/** - * Get lib3270 selection as a g_malloc buffer. - * - * @param widget Widget containing the desired section. - * - * @return NULL if error, otherwise the selected buffer contents (release with g_free). - * - */ -LIB3270_EXPORT gchar * v3270_get_selected(GtkWidget *widget, gboolean cut) -{ - const char *text; - - g_return_val_if_fail(GTK_IS_V3270(widget),NULL); - - text = update_selected_text(widget,cut); - - if(text) - return g_convert(text, -1, "UTF-8", lib3270_get_display_charset(GTK_V3270(widget)->host), NULL, NULL, NULL); - - return NULL; -} - -LIB3270_EXPORT gchar * v3270_get_copy(GtkWidget *widget) -{ - const char *text; - g_return_val_if_fail(GTK_IS_V3270(widget),NULL); - - text = GTK_V3270(widget)->selection.text; - - if(!text) - text = update_selected_text(widget,FALSE); - - if(text) - return g_convert(text, -1, "UTF-8", lib3270_get_display_charset(GTK_V3270(widget)->host), NULL, NULL, NULL); - - return NULL; -} - -LIB3270_EXPORT void v3270_set_copy(GtkWidget *widget, const gchar *text) -{ - v3270 * terminal; - gchar * isotext; - - g_return_if_fail(GTK_IS_V3270(widget)); - - terminal = GTK_V3270(widget); - v3270_clear_clipboard(terminal); - - if(!text) - { - /* No string, signal clipboard clear and return */ - g_signal_emit(widget,v3270_widget_signal[V3270_SIGNAL_CLIPBOARD], 0, FALSE); - return; - } - - /* Received text, replace the selection buffer */ - terminal->table = 0; - isotext = g_convert(text, -1, lib3270_get_display_charset(terminal->host), "UTF-8", NULL, NULL, NULL); - - if(!isotext) - { - /* No string, signal clipboard clear and return */ - g_signal_emit(widget,v3270_widget_signal[V3270_SIGNAL_CLIPBOARD], 0, FALSE); - return; - } - - terminal->selection.text = lib3270_strdup(isotext); - - g_free(isotext); - - g_signal_emit(widget,v3270_widget_signal[V3270_SIGNAL_CLIPBOARD], 0, TRUE); -} - -static void update_system_clipboard(GtkWidget *widget) -{ - if(GTK_V3270(widget)->selection.text) - { - GtkClipboard * clipboard = gtk_widget_get_clipboard(widget,GDK_SELECTION_CLIPBOARD); - - if(gtk_clipboard_set_with_owner( clipboard, - targets, - G_N_ELEMENTS(targets), - (GtkClipboardGetFunc) clipboard_get, - (GtkClipboardClearFunc) clipboard_clear, - G_OBJECT(widget) - )) - { - gtk_clipboard_set_can_store(clipboard,targets,1); - } - - g_signal_emit(widget,v3270_widget_signal[V3270_SIGNAL_CLIPBOARD], 0, TRUE); - } -} - - -LIB3270_EXPORT void v3270_copy_append(GtkWidget *widget) -{ - v3270 * terminal; - char * str; - - g_return_if_fail(GTK_IS_V3270(widget)); - - terminal = GTK_V3270(widget); - - if(!terminal->selection.text) - { - // Clipboard is empty, do a single copy - v3270_copy(widget, V3270_SELECT_TEXT, FALSE); - return; - } - - str = lib3270_get_selected(terminal->host); - - if(str) - { - size_t len = strlen(terminal->selection.text)+strlen(str)+2; - - terminal->selection.text = lib3270_realloc(terminal->selection.text,len); - - strncat(terminal->selection.text,"\n",len); - strncat(terminal->selection.text,str,len); - - lib3270_free(str); - } - - update_system_clipboard(widget); - -} - -LIB3270_EXPORT void v3270_copy(GtkWidget *widget, V3270_SELECT_FORMAT mode, gboolean cut) -{ - g_return_if_fail(GTK_IS_V3270(widget)); - GTK_V3270(widget)->table = (mode == V3270_SELECT_TABLE ? 1 : 0); - update_selected_text(widget,cut); - update_system_clipboard(widget); -} - -#ifdef _WIN32 - -LIB3270_EXPORT void v3270_paste(GtkWidget *widget) -{ - HGLOBAL hglb; - - if (!IsClipboardFormatAvailable(CF_TEXT)) - return; - - if (!OpenClipboard(NULL)) - return; - - hglb = GetClipboardData(CF_TEXT); - if (hglb != NULL) - { - LPTSTR lptstr = GlobalLock(hglb); - if (lptstr != NULL) - { - v3270_paste_string(widget,lptstr,"CP1252"); - GlobalUnlock(hglb); - } - } - - CloseClipboard(); - -} - -#else - -static void text_received(G_GNUC_UNUSED GtkClipboard *clipboard, const gchar *text, GtkWidget *widget) -{ - v3270_paste_string(widget,text,"UTF-8"); -} - -LIB3270_EXPORT void v3270_paste(GtkWidget *widget) -{ - gtk_clipboard_request_text(gtk_widget_get_clipboard(widget,GDK_SELECTION_CLIPBOARD),(GtkClipboardTextReceivedFunc) text_received,(gpointer) widget); -} - -#endif // _WIN32 - -LIB3270_EXPORT void v3270_paste_string(GtkWidget *widget, const gchar *text, const gchar *encoding) -{ - gchar * buffer = NULL; - H3270 * session = v3270_get_session(widget); - const gchar * charset = lib3270_get_display_charset(session); - gboolean next; - - if(!text) - return; - else if(g_ascii_strcasecmp(encoding,charset)) - buffer = g_convert(text, -1, charset, encoding, NULL, NULL, NULL); - else - buffer = g_strdup(text); - - if(!buffer) - { - /* Conversion failed, update special chars and try again */ - size_t f; - - static const struct _xlat - { - const gchar *from; - const gchar *to; - } xlat[] = - { - { "–", "-" }, - { "→", "->" }, - { "←", "<-" }, - { "©", "(c)" }, - { "↔", "<->" }, - { "™", "(TM)" }, - { "®", "(R)" }, - { "“", "\"" }, - { "”", "\"" }, - { "…", "..." }, - { "•", "*" }, - { "․", "." }, - { "·", "*" }, - - }; - - gchar *string = g_strdup(text); - - // FIXME (perry#1#): Is there any better way for a "sed" here? - for(f=0;fmessage, ln[f]); - - gtk_dialog_run(GTK_DIALOG (dialog)); - gtk_widget_destroy(dialog); - - break; - } - else - { - g_free(str); - } - - } - g_strfreev(ln); - - } - - g_free(string); - } - - if(buffer) - { - /* Remove TABS */ - gchar *ptr; - - for(ptr = buffer;*ptr;ptr++) - { - if(*ptr == '\t') - *ptr = ' '; - } - } - else - { - g_signal_emit(widget,v3270_widget_signal[V3270_SIGNAL_PASTENEXT], 0, FALSE); - return; - } - - next = lib3270_paste(session,(unsigned char *) buffer) ? TRUE : FALSE; - - g_free(buffer); - - g_signal_emit(widget,v3270_widget_signal[V3270_SIGNAL_PASTENEXT], 0, next); - -} - -LIB3270_EXPORT void v3270_unselect(GtkWidget *widget) -{ - v3270_disable_updates(widget); - lib3270_unselect(v3270_get_session(widget)); - v3270_enable_updates(widget); -} - -gboolean v3270_get_selection_bounds(GtkWidget *widget, gint *start, gint *end) -{ - g_return_val_if_fail(GTK_IS_V3270(widget),FALSE); - return lib3270_get_selection_bounds(GTK_V3270(widget)->host,start,end) == 0 ? FALSE : TRUE; -} - -gchar * v3270_get_region(GtkWidget *widget, gint start_pos, gint end_pos, gboolean all) -{ - char * str; - gchar * utftext; - - g_return_val_if_fail(GTK_IS_V3270(widget),NULL); - - str = lib3270_get_region(GTK_V3270(widget)->host,start_pos,end_pos,all); - if(!str) - return NULL; - - utftext = g_convert(str, -1, "UTF-8", lib3270_get_display_charset(GTK_V3270(widget)->host), NULL, NULL, NULL); - - lib3270_free(str); - - return utftext; -} - -LIB3270_EXPORT void v3270_select_region(GtkWidget *widget, gint start, gint end) -{ - g_return_if_fail(GTK_IS_V3270(widget)); - lib3270_select_region(GTK_V3270(widget)->host,start,end); -} - -LIB3270_EXPORT void v3270_select_all(GtkWidget *widget) -{ - g_return_if_fail(GTK_IS_V3270(widget)); - v3270_disable_updates(widget); - lib3270_select_all(v3270_get_session(widget)); - v3270_enable_updates(widget); -} - - diff --git a/v3270.cbp b/v3270.cbp index fd3df99..6c4950d 100644 --- a/v3270.cbp +++ b/v3270.cbp @@ -42,6 +42,18 @@ + + + + + + + + @@ -130,6 +142,7 @@ + @@ -163,6 +176,9 @@ + + @@ -185,9 +201,6 @@ - - -- libgit2 0.21.2