From d21447d096a320a08b3efb2b8768fad0dcdcfd64 Mon Sep 17 00:00:00 2001 From: Vincent Sanders Date: Thu, 5 May 2016 22:28:51 +0100 Subject: move frontends into sub directory --- frontends/amiga/clipboard.c | 374 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 374 insertions(+) create mode 100644 frontends/amiga/clipboard.c (limited to 'frontends/amiga/clipboard.c') diff --git a/frontends/amiga/clipboard.c b/frontends/amiga/clipboard.c new file mode 100644 index 000000000..12ceb0f09 --- /dev/null +++ b/frontends/amiga/clipboard.c @@ -0,0 +1,374 @@ +/* + * Copyright 2008-2012 Chris Young + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "utils/nsoption.h" +#include "utils/utf8.h" +#include "utils/nsurl.h" +#include "content/hlcache.h" +#include "desktop/browser.h" +#include "desktop/plotters.h" +#include "desktop/textinput.h" +#include "desktop/gui_window.h" +#include "desktop/gui_clipboard.h" + +#include "amiga/bitmap.h" +#include "amiga/clipboard.h" +#include "amiga/drag.h" +#include "amiga/filetype.h" +#include "amiga/gui.h" +#include "amiga/iff_cset.h" +#include "amiga/iff_dr2d.h" +#include "amiga/menu.h" +#include "amiga/misc.h" +#include "amiga/utf8.h" + +#define ID_UTF8 MAKE_ID('U','T','F','8') + +struct IFFHandle *iffh = NULL; + +static struct IFFHandle *ami_clipboard_init_internal(int unit) +{ + struct IFFHandle *iffhandle = NULL; + + if((iffhandle = AllocIFF())) + { + if((iffhandle->iff_Stream = (ULONG)OpenClipboard(unit))) + { + InitIFFasClip(iffhandle); + } + } + + return iffhandle; +} + +void ami_clipboard_init(void) +{ + iffh = ami_clipboard_init_internal(0); +} + +static void ami_clipboard_free_internal(struct IFFHandle *iffhandle) +{ + if(iffhandle == NULL) return; + if(iffhandle->iff_Stream) CloseClipboard((struct ClipboardHandle *)iffhandle->iff_Stream); + FreeIFF(iffhandle); +} + +void ami_clipboard_free(void) +{ + ami_clipboard_free_internal(iffh); +} + +void gui_start_selection(struct gui_window *g) +{ + if(!g) return; + if(!g->shared->win) return; + if(nsoption_bool(kiosk_mode) == true) return; + + OnMenu(g->shared->win, AMI_MENU_CLEAR); + OnMenu(g->shared->win, AMI_MENU_COPY); + + if (browser_window_get_editor_flags(g->bw) & BW_EDITOR_CAN_CUT) + OnMenu(g->shared->win, AMI_MENU_CUT); +} + +static char *ami_clipboard_cat_collection(struct CollectionItem *ci, LONG codeset, size_t *text_length) +{ + struct CollectionItem *ci_new = NULL, *ci_next = NULL, *ci_curr = ci; + size_t len = 0; + char *text = NULL, *p; + + /* Scan the collected chunks to find out the total size. + * If they are not in UTF-8, convert the chunks first and create a new CollectionItem list. + */ + do { + switch(codeset) { + case 106: + len += ci_curr->ci_Size; + break; + + case 0: + if(ci_new) { + ci_next->ci_Next = ami_misc_allocvec_clear(sizeof(struct CollectionItem), 0); + ci_next = ci_next->ci_Next; + } else { + ci_new = ami_misc_allocvec_clear(sizeof(struct CollectionItem), 0); + ci_next = ci_new; + } + + utf8_from_local_encoding(ci_curr->ci_Data, ci_curr->ci_Size, (char **)&ci_next->ci_Data); + ci_next->ci_Size = strlen(ci_next->ci_Data); + len += ci_next->ci_Size; + break; + + default: + if(ci_new) { + ci_next->ci_Next = ami_misc_allocvec_clear(sizeof(struct CollectionItem), 0); + ci_next = ci_next->ci_Next; + } else { + ci_new = ami_misc_allocvec_clear(sizeof(struct CollectionItem), 0); + ci_next = ci_new; + } + + utf8_from_enc(ci_curr->ci_Data, + (const char *)ObtainCharsetInfo(DFCS_NUMBER, + codeset, DFCS_MIMENAME), + ci_curr->ci_Size, (char **)&ci_next->ci_Data, NULL); + ci_next->ci_Size = strlen(ci_next->ci_Data); + len += ci_next->ci_Size; + break; + } + } 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; + + if(ci_new) { + ci_curr = ci_new; + } else { + ci_curr = ci; + } + + do { + p -= ci_curr->ci_Size; + memcpy(p, ci_curr->ci_Data, ci_curr->ci_Size); + ci_next = ci_curr->ci_Next; + + if(ci_new) { + free(ci_curr->ci_Data); + FreeVec(ci_curr); + } + } while ((ci_curr = ci_next)); + + *text_length = len; + return text; +} + +static void gui_get_clipboard(char **buffer, size_t *length) +{ + struct CollectionItem *ci = NULL; + struct StoredProperty *sp = NULL; + struct CSet *cset; + + if(OpenIFF(iffh,IFFF_READ)) return; + + if(CollectionChunk(iffh,ID_FTXT,ID_CHRS)) return; + if(PropChunk(iffh,ID_FTXT,ID_CSET)) return; + if(CollectionChunk(iffh,ID_FTXT,ID_UTF8)) return; + if(StopOnExit(iffh, ID_FTXT, ID_FORM)) return; + + ParseIFF(iffh,IFFPARSE_SCAN); + + 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))) { + LONG codeset = 0; + if((sp = FindProp(iffh, ID_FTXT, ID_CSET))) { + cset = (struct CSet *)sp->sp_Data; + codeset = cset->CodeSet; + } + *buffer = ami_clipboard_cat_collection(ci, codeset, length); + } + + CloseIFF(iffh); +} + +static void gui_set_clipboard(const char *buffer, size_t length, + nsclipboard_styles styles[], int n_styles) +{ + char *text; + struct CSet cset = {0, {0}}; + + if(buffer == NULL) return; + + if(!(OpenIFF(iffh, IFFF_WRITE))) + { + if(!(PushChunk(iffh, ID_FTXT, ID_FORM, IFFSIZE_UNKNOWN))) + { + if(nsoption_bool(clipboard_write_utf8)) + { + if(!(PushChunk(iffh, 0, ID_CSET, 32))) + { + cset.CodeSet = 106; // UTF-8 + WriteChunkBytes(iffh, &cset, 32); + PopChunk(iffh); + } + } + } + else + { + PopChunk(iffh); + } + + if(!(PushChunk(iffh, 0, ID_CHRS, IFFSIZE_UNKNOWN))) { + if(nsoption_bool(clipboard_write_utf8)) { + WriteChunkBytes(iffh, buffer, length); + } else { + if(utf8_to_local_encoding(buffer, length, &text) == NSERROR_OK) { + char *p; + + p = text; + + while(*p != '\0') { + if(*p == 0xa0) *p = 0x20; + p++; + } + WriteChunkBytes(iffh, text, strlen(text)); + ami_utf8_free(text); + } + } + + PopChunk(iffh); + } else { + PopChunk(iffh); + } + + if(!(PushChunk(iffh, 0, ID_UTF8, IFFSIZE_UNKNOWN))) { + WriteChunkBytes(iffh, buffer, length); + PopChunk(iffh); + } else { + PopChunk(iffh); + } + CloseIFF(iffh); + } +} + +void ami_drag_selection(struct gui_window *g) +{ + int x; + int y; + char *utf8text; + char *sel; + struct IFFHandle *old_iffh = iffh; + struct gui_window_2 *gwin = ami_window_at_pointer(AMINS_WINDOW); + + /* NB: 'gwin' is at the drop point, 'g' is where the selection was dragged from. + * These may be different if the selection has been dragged between windows. */ + + if(!gwin) + { + DisplayBeep(scrn); + return; + } + + x = gwin->win->MouseX; + y = gwin->win->MouseY; + + if(ami_text_box_at_point(gwin, (ULONG *)&x, (ULONG *)&y)) + { + iffh = ami_clipboard_init_internal(1); + + browser_window_key_press(g->bw, NS_KEY_COPY_SELECTION); + browser_window_mouse_click(gwin->gw->bw, BROWSER_MOUSE_PRESS_1, x, y); + browser_window_key_press(gwin->gw->bw, NS_KEY_PASTE); + + ami_clipboard_free_internal(iffh); + iffh = old_iffh; + } + else + { + x = gwin->win->MouseX; + y = gwin->win->MouseY; + + if(ami_gadget_hit(gwin->objects[GID_URL], x, y)) + { + if((sel = browser_window_get_selection(g->bw))) + { + utf8text = ami_utf8_easy(sel); + RefreshSetGadgetAttrs((struct Gadget *)gwin->objects[GID_URL], + gwin->win, NULL, STRINGA_TextVal, utf8text, TAG_DONE); + free(sel); + ami_utf8_free(utf8text); + } + } + else if(ami_gadget_hit(gwin->objects[GID_SEARCHSTRING], x, y)) + { + if((sel = browser_window_get_selection(g->bw))) + { + utf8text = ami_utf8_easy(sel); + RefreshSetGadgetAttrs((struct Gadget *)gwin->objects[GID_SEARCHSTRING], + gwin->win, NULL, STRINGA_TextVal, utf8text, TAG_DONE); + free(sel); + ami_utf8_free(utf8text); + } + } + else + { + DisplayBeep(scrn); + } + } +} + +bool ami_easy_clipboard(const char *text) +{ + gui_set_clipboard(text, strlen(text), NULL, 0); + return true; +} + +bool ami_easy_clipboard_bitmap(struct bitmap *bitmap) +{ + Object *dto = NULL; + + if((dto = ami_datatype_object_from_bitmap(bitmap))) + { + DoDTMethod(dto,NULL,NULL,DTM_COPY,NULL); + DisposeDTObject(dto); + } + return true; +} + +#ifdef WITH_NS_SVG +bool ami_easy_clipboard_svg(struct hlcache_handle *c) +{ + const char *source_data; + ULONG source_size; + + if(ami_mime_compare(c, "svg") == false) return false; + if((source_data = content_get_source_data(c, &source_size)) == NULL) return false; + + if(!(OpenIFF(iffh,IFFF_WRITE))) + { + ami_svg_to_dr2d(iffh, source_data, source_size, nsurl_access(hlcache_handle_get_url(c))); + CloseIFF(iffh); + } + + return true; +} +#endif + +static struct gui_clipboard_table clipboard_table = { + .get = gui_get_clipboard, + .set = gui_set_clipboard, +}; + +struct gui_clipboard_table *amiga_clipboard_table = &clipboard_table; -- cgit v1.2.3