From 5aae2c3ed0d2811b620d042c101c94c07bedf889 Mon Sep 17 00:00:00 2001 From: Chris Young Date: Tue, 8 Jan 2013 23:01:57 +0000 Subject: [PATCH 1/4] Fix drag selection --- amiga/clipboard.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/amiga/clipboard.c b/amiga/clipboard.c index 018ea2604..ab064ba6b 100755 --- a/amiga/clipboard.c +++ b/amiga/clipboard.c @@ -320,14 +320,13 @@ void ami_drag_selection(struct selection *s) if(ami_text_box_at_point(gwin, (ULONG *)&x, (ULONG *)&y)) { iffh = ami_clipboard_init_internal(1); -#if 0 -/* TODO: fix this */ - if(gui_copy_to_clipboard(s)) + + if(selection_copy_to_clipboard(s)) { browser_window_mouse_click(gwin->bw, BROWSER_MOUSE_PRESS_1, x, y); browser_window_key_press(gwin->bw, KEY_PASTE); } -#endif + ami_clipboard_free_internal(iffh); iffh = old_iffh; } From 7ae27476a70d4307719b9007c18ded659e5b520e Mon Sep 17 00:00:00 2001 From: Chris Young Date: Tue, 8 Jan 2013 23:44:13 +0000 Subject: [PATCH 2/4] Re-implement reading the clipboard using CollectionChunk; this removes the need for an initial UTF8 chunk scan and allows the chunks to be collated before sending back to the core. Untested and length calculations ignore charset conversion. --- amiga/clipboard.c | 113 +++++++++++++++++++++++++++++----------------- 1 file changed, 71 insertions(+), 42 deletions(-) diff --git a/amiga/clipboard.c b/amiga/clipboard.c index ab064ba6b..0897357ab 100755 --- a/amiga/clipboard.c +++ b/amiga/clipboard.c @@ -137,10 +137,62 @@ bool ami_clipboard_check_for_utf8(struct IFFHandle *iffh) { return utf8_chunk; } +char *ami_clipboard_cat_collection(struct CollectionItem *ci, LONG codeset, size_t *text_length) +{ + struct CollectionItem *ci_curr = ci; + size_t len = 0; + char *text = NULL, *p, *clip; + + /* Scan the collected chunks to find out the total size */ + do { + len += ci_curr->ci_Size; + } while (ci_curr = ci_curr->ci_Next); + + text = malloc(len); + + if(text == NULL) return NULL; + + /* p points to the end of the buffer. This is because the chunks are + * in the list in reverse order. */ + p = text + len; + ci_curr = ci; + + do { + p -= ci_curr->ci_Size; + + switch(codeset) { + case 106: + memcpy(p, ci_curr->ci_Data, ci_curr->ci_Size); + break; + + /* If codeset isn't 106 (UTF-8) we need to convert to UTF-8. + * TODO: ensure buffer is big enough for converted text */ + + case 0: + utf8_from_local_encoding(ci_curr->ci_Data, ci_curr->ci_Size, &clip); + memcpy(p, clip, ci_curr->ci_Size); + free(clip); + break; + + default: + utf8_from_enc(ci_curr->ci_Data, + (const char *)ObtainCharsetInfo(DFCS_NUMBER, + codeset, DFCS_MIMENAME), + ci_curr->ci_Size, &clip); + memcpy(p, clip, ci_curr->ci_Size); + free(clip); + break; + } + } while (ci_curr = ci_curr->ci_Next); + + *text_length = len; + return text; +} + void gui_get_clipboard(char **buffer, size_t *length) { - /* This and the other clipboard code is heavily based on the RKRM examples */ struct ContextNode *cn; + struct CollectionItem *ci = NULL; ULONG rlen=0,error; struct CSet cset; LONG codeset = 0; @@ -150,17 +202,11 @@ void gui_get_clipboard(char **buffer, size_t *length) cset.CodeSet = 0; - if(ami_clipboard_check_for_utf8(iffh)) - utf8_chunks = true; - if(OpenIFF(iffh,IFFF_READ)) return; - if(utf8_chunks == false) { - if(StopChunk(iffh,ID_FTXT,ID_CHRS)) return; - if(StopChunk(iffh,ID_FTXT,ID_CSET)) return; - } else { - if(StopChunk(iffh,ID_FTXT,ID_UTF8)) return; - } + if(CollectionChunk(iffh,ID_FTXT,ID_CHRS)) return; + if(StopChunk(iffh,ID_FTXT,ID_CSET)) return; + if(CollectionChunk(iffh,ID_FTXT,ID_UTF8)) return; while(1) { @@ -170,43 +216,26 @@ void gui_get_clipboard(char **buffer, size_t *length) cn = CurrentChunk(iffh); - if((cn)&&(cn->cn_Type == ID_FTXT)&&(cn->cn_ID == ID_CSET)&&(utf8_chunks == false)) + if((cn)&&(cn->cn_Type == ID_FTXT)&&(cn->cn_ID == ID_CSET)) { - rlen = ReadChunkBytes(iffh,&cset,32); + /* Ideally when we stop here, we need to convert all CHRS chunks up to this + * point based on the previous codeset. However, for simplicity, we just + * assume only one CSET chunk is present and only take note of the last + * CSET chunk if there is more than one. + */ + + rlen = ReadChunkBytes(iffh, &cset, 32); if(cset.CodeSet == 1) codeset = 106; else codeset = cset.CodeSet; } - - if((cn)&&(cn->cn_Type == ID_FTXT)&&(cn->cn_ID == ID_CHRS)&&(utf8_chunks == false)) - { - while((rlen = ReadChunkBytes(iffh,readbuf,1024)) > 0) - { - if(codeset == 0) - { - utf8_from_local_encoding(readbuf,rlen,&clip); - } - else - { - utf8_from_enc(readbuf, - (const char *)ObtainCharsetInfo(DFCS_NUMBER, - codeset, DFCS_MIMENAME), - rlen, &clip); - } - - //browser_window_paste_text(g->shared->bw,clip,rlen,true); - } - if(rlen < 0) error = rlen; - } - - if((cn)&&(cn->cn_Type == ID_FTXT)&&(cn->cn_ID == ID_UTF8)&&(utf8_chunks == true)) - { - while((rlen = ReadChunkBytes(iffh, readbuf, 1024)) > 0) - { - //browser_window_paste_text(g->shared->bw, readbuf, rlen, true); - } - if(rlen < 0) error = rlen; - } } + + if(ci = FindCollection(iffh, ID_FTXT, ID_UTF8)) { + *buffer = ami_clipboard_cat_collection(ci, 106, length); + } else if(ci = FindCollection(iffh, ID_FTXT, ID_CHRS)) { + *buffer = ami_clipboard_cat_collection(ci, codeset, length); + } + CloseIFF(iffh); } From bded644d7ffe804bfc00e17a0b7ac49eec3c2e27 Mon Sep 17 00:00:00 2001 From: Ole Loots Date: Wed, 9 Jan 2013 01:12:30 +0100 Subject: [PATCH 3/4] Fixes for new clipboard interface. --- atari/ctxmenu.c | 4 +- atari/gui.c | 186 ++++++++++++++++++------------------------------ atari/toolbar.h | 2 +- 3 files changed, 73 insertions(+), 119 deletions(-) diff --git a/atari/ctxmenu.c b/atari/ctxmenu.c index 1a1755b12..84f5d870d 100644 --- a/atari/ctxmenu.c +++ b/atari/ctxmenu.c @@ -175,8 +175,8 @@ void context_popup( struct gui_window * gw, short x, short y ) browser_window_key_press( gw->browser->bw, KEY_CUT_SELECTION ); break; - case POP_CTX_PASTE_SEL: - gui_paste_from_clipboard(gw, x, y); + case POP_CTX_PASTE_SEL: + browser_window_key_press(gw->browser->bw, KEY_PASTE); break; case POP_CTX_SELECT_ALL: diff --git a/atari/gui.c b/atari/gui.c index c2158e05e..193a8920a 100755 --- a/atari/gui.c +++ b/atari/gui.c @@ -612,125 +612,79 @@ void gui_drag_save_selection(struct selection *s, struct gui_window *w) void gui_start_selection(struct gui_window *w) { - gui_empty_clipboard(); -} -void gui_paste_from_clipboard(struct gui_window *w, int x, int y) -{ - char * clip = scrap_txt_read( &app ); - if( clip == NULL ) - return; - int clip_length = strlen( clip ); - if (clip_length > 0) { - char *utf8; - utf8_convert_ret ret; - /* Clipboard is in local encoding so - * convert to UTF8 */ - ret = utf8_from_local_encoding(clip, - clip_length, &utf8); - if (ret == UTF8_CONVERT_OK) { - browser_window_paste_text(w->browser->bw, utf8, - strlen(utf8), true); - free(utf8); - } - free( clip ); - } -} +} + +/** + * Core asks front end for clipboard contents. + * + * \param buffer UTF-8 text, allocated by front end, ownership yeilded to core + * \param length Byte length of UTF-8 text in buffer + */ +void gui_get_clipboard(char **buffer, size_t *length) +{ + char *clip; + size_t clip_len; + + *length = 0; + *buffer = 0; + + clip = scrap_txt_read(&app); + + if(clip == NULL){ + return; + } else { + + // clipboard is in atari encoding, convert it to utf8: + + char *utf8 = NULL; + utf8_convert_ret ret; + + clip_len = strlen(clip); + if (clip_len > 0) { + ret = utf8_to_local_encoding(clip, clip_len, &utf8); + if (ret == UTF8_CONVERT_OK && utf8 != NULL) { + *buffer = utf8; + *length = strlen(utf8); + } + else { + assert(ret == UTF8_CONVERT_OK && utf8 != NULL); + } + } -bool gui_empty_clipboard(void) -{ - if( tmp_clipboard != NULL ){ - free( tmp_clipboard ); - tmp_clipboard = NULL; - } - return true; -} - -bool gui_add_to_clipboard(const char *text_utf8, size_t length_utf8, bool space, - const plot_font_style_t *fstyle) -{ - LOG(("(%s): %s (%d)\n", (space)?"space":"", (char*)text_utf8, (int)length_utf8)); - char * oldptr = tmp_clipboard; - size_t oldlen = 0; - size_t newlen = 0; - char * text = NULL; - char * text2 = NULL; - bool retval; - int length = 0; - if( length_utf8 > 0 && text_utf8 != NULL ) { - utf8_to_local_encoding(text_utf8,length_utf8,&text); - if( text == NULL ) { - LOG(("Conversion failed (%s)", text_utf8)); - goto error; - } else { - text2 = text; - } - } else { - if( space == false ) { - goto success; - } - text = malloc(length + 2); - if( text == NULL ) { - goto error; - } - text2 = text; - text[length+1] = 0; - memset(text, ' ', length+1); - } - length = strlen(text); - if( tmp_clipboard != NULL ) { - oldlen = strlen( tmp_clipboard ); - } - newlen = oldlen + length + 1; - if( tmp_clipboard == NULL){ - tmp_clipboard = malloc(newlen); - if( tmp_clipboard == NULL ) { - goto error; - } - strncpy(tmp_clipboard, text, newlen); - } else { - tmp_clipboard = realloc( tmp_clipboard, newlen); - if( tmp_clipboard == NULL ) { - goto error; - } - strncpy(tmp_clipboard, oldptr, newlen); - strncat(tmp_clipboard, text, newlen-oldlen); - } - goto success; - -error: - retval = false; - goto fin; - -success: - retval = true; - -fin: - if( text2 != NULL ) - free( text2 ); - return(retval); - -} - -bool gui_commit_clipboard(void) -{ - int r = scrap_txt_write(&app, tmp_clipboard); - return( (r>0)?true:false ); -} - -bool gui_copy_to_clipboard(struct selection *s) -{ - bool ret = false; - if( s->defined ) { - gui_empty_clipboard(); - if(selection_copy_to_clipboard(s)){ - ret = gui_commit_clipboard(); - } - } - gui_empty_clipboard(); - return ret; -} + free(clip); + } +} + +/** + * Core tells front end to put given text in clipboard + * + * \param buffer UTF-8 text, owned by core + * \param length Byte length of UTF-8 text in buffer + * \param styles Array of styles given to text runs, owned by core, or NULL + * \param n_styles Number of text run styles in array + */ +void gui_set_clipboard(const char *buffer, size_t length, + nsclipboard_styles styles[], int n_styles) +{ + if (length > 0 && buffer != NULL) { + + // convert utf8 input to atari encoding: + + utf8_convert_ret ret; + char *clip = NULL; + ret = utf8_to_local_encoding(buffer,length, &clip); + if (ret == UTF8_CONVERT_OK) { + scrap_txt_write(&app, clip); + } else { + assert(ret == UTF8_CONVERT_OK); + } + free(clip); + } +} + + void gui_create_form_select_menu(struct browser_window *bw, struct form_control *control) diff --git a/atari/toolbar.h b/atari/toolbar.h index 7f8640843..69908de35 100755 --- a/atari/toolbar.h +++ b/atari/toolbar.h @@ -56,7 +56,7 @@ struct s_tb_button struct s_url_widget { bool redraw; /* widget is only redrawn when this flag is set */ - struct text_area *textarea; + struct textarea *textarea; COMPONENT * comp; GRECT rdw_area; }; From 1f693a8677629e341e62731d9d1a78e6470f1719 Mon Sep 17 00:00:00 2001 From: Ole Loots Date: Wed, 9 Jan 2013 01:39:34 +0100 Subject: [PATCH 4/4] Removed obsolete variable tmp_clipboard --- atari/gui.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/atari/gui.c b/atari/gui.c index 193a8920a..8f5591307 100755 --- a/atari/gui.c +++ b/atari/gui.c @@ -77,8 +77,7 @@ #include "cflib.h" #define TODO() (0)/*printf("%s Unimplemented!\n", __FUNCTION__)*/ - -char *tmp_clipboard; + struct gui_window *input_window = NULL; struct gui_window *window_list = NULL; void * h_gem_rsrc; @@ -765,10 +764,6 @@ void gui_quit(void) } LOG(("Shutting down plotter")); plot_finalise(); - if( tmp_clipboard != NULL ){ - free( tmp_clipboard ); - tmp_clipboard = NULL; - } LOG(("done")); }