NetSurf
clipboard.c
Go to the documentation of this file.
1/*
2 * Copyright 2008-2012 Chris Young <chris@unsatisfactorysoftware.co.uk>
3 *
4 * This file is part of NetSurf, http://www.netsurf-browser.org/
5 *
6 * NetSurf is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
9 *
10 * NetSurf is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19#include <stdlib.h>
20#include <string.h>
21#include <proto/iffparse.h>
22#include <proto/intuition.h>
23#include <proto/exec.h>
24#include <proto/datatypes.h>
25#include <proto/diskfont.h>
26
27#include <diskfont/diskfonttag.h>
28#include <datatypes/textclass.h>
29#include <datatypes/pictureclass.h>
30
31#include "utils/nsoption.h"
32#include "utils/utf8.h"
33#include "utils/nsurl.h"
34#include "netsurf/content.h"
36#include "netsurf/plotters.h"
37#include "netsurf/keypress.h"
38#include "netsurf/window.h"
39#include "netsurf/clipboard.h"
40
41#include "amiga/bitmap.h"
42#include "amiga/clipboard.h"
43#include "amiga/drag.h"
44#include "amiga/filetype.h"
45#include "amiga/gui.h"
46#include "amiga/iff_cset.h"
47#include "amiga/iff_dr2d.h"
48#include "amiga/gui_menu.h"
49#include "amiga/utf8.h"
50
51#define ID_UTF8 MAKE_ID('U','T','F','8')
52
53static struct IFFHandle *iffh = NULL;
54
55static struct IFFHandle *ami_clipboard_init_internal(int unit)
56{
57 struct IFFHandle *iffhandle = NULL;
58
59 if((iffhandle = AllocIFF()))
60 {
61 if((iffhandle->iff_Stream = (ULONG)OpenClipboard(unit)))
62 {
63 InitIFFasClip(iffhandle);
64 }
65 }
66
67 return iffhandle;
68}
69
71{
73}
74
75static void ami_clipboard_free_internal(struct IFFHandle *iffhandle)
76{
77 if(iffhandle == NULL) return;
78 if(iffhandle->iff_Stream) CloseClipboard((struct ClipboardHandle *)iffhandle->iff_Stream);
79 FreeIFF(iffhandle);
80}
81
83{
85}
86
88{
89 if(!g) return;
90 if(!ami_gui_get_window(g)) return;
91 if(nsoption_bool(kiosk_mode) == true) return;
92
95
98}
99
100static char *ami_clipboard_cat_collection(struct CollectionItem *ci, LONG codeset, size_t *text_length)
101{
102 struct CollectionItem *ci_new = NULL, *ci_next = NULL, *ci_curr = ci;
103 size_t len = 0;
104 char *text = NULL, *p;
105
106 /* Scan the collected chunks to find out the total size.
107 * If they are not in UTF-8, convert the chunks first and create a new CollectionItem list.
108 */
109 do {
110 switch(codeset) {
111 case 106:
112 len += ci_curr->ci_Size;
113 break;
114
115 case 0:
116 if(ci_new) {
117 ci_next->ci_Next = calloc(1, sizeof(struct CollectionItem));
118 ci_next = ci_next->ci_Next;
119 } else {
120 ci_new = calloc(1, sizeof(struct CollectionItem));
121 ci_next = ci_new;
122 }
123
124 utf8_from_local_encoding(ci_curr->ci_Data, ci_curr->ci_Size, (char **)&ci_next->ci_Data);
125 ci_next->ci_Size = strlen(ci_next->ci_Data);
126 len += ci_next->ci_Size;
127 break;
128
129 default:
130 if(ci_new) {
131 ci_next->ci_Next = calloc(1, sizeof(struct CollectionItem));
132 ci_next = ci_next->ci_Next;
133 } else {
134 ci_new = calloc(1, sizeof(struct CollectionItem));
135 ci_next = ci_new;
136 }
137
138 utf8_from_enc(ci_curr->ci_Data,
139 (const char *)ObtainCharsetInfo(DFCS_NUMBER,
140 codeset, DFCS_MIMENAME),
141 ci_curr->ci_Size, (char **)&ci_next->ci_Data, NULL);
142 ci_next->ci_Size = strlen(ci_next->ci_Data);
143 len += ci_next->ci_Size;
144 break;
145 }
146 } while ((ci_curr = ci_curr->ci_Next));
147
148 text = malloc(len);
149
150 if(text == NULL) return NULL;
151
152 /* p points to the end of the buffer. This is because the chunks are
153 * in the list in reverse order. */
154 p = text + len;
155
156 if(ci_new) {
157 ci_curr = ci_new;
158 } else {
159 ci_curr = ci;
160 }
161
162 do {
163 p -= ci_curr->ci_Size;
164 memcpy(p, ci_curr->ci_Data, ci_curr->ci_Size);
165 ci_next = ci_curr->ci_Next;
166
167 if(ci_new) {
168 free(ci_curr->ci_Data);
169 free(ci_curr);
170 }
171 } while ((ci_curr = ci_next));
172
173 *text_length = len;
174 return text;
175}
176
177static void gui_get_clipboard(char **buffer, size_t *length)
178{
179 struct CollectionItem *ci = NULL;
180 struct StoredProperty *sp = NULL;
181 struct CSet *cset;
182
183 if(OpenIFF(iffh,IFFF_READ)) return;
184
185 if(CollectionChunk(iffh,ID_FTXT,ID_CHRS)) return;
186 if(PropChunk(iffh,ID_FTXT,ID_CSET)) return;
187 if(CollectionChunk(iffh,ID_FTXT,ID_UTF8)) return;
188 if(StopOnExit(iffh, ID_FTXT, ID_FORM)) return;
189
190 ParseIFF(iffh,IFFPARSE_SCAN);
191
192 if((ci = FindCollection(iffh, ID_FTXT, ID_UTF8))) {
193 *buffer = ami_clipboard_cat_collection(ci, 106, length);
194 } else if((ci = FindCollection(iffh, ID_FTXT, ID_CHRS))) {
195 LONG codeset = 0;
196 if((sp = FindProp(iffh, ID_FTXT, ID_CSET))) {
197 cset = (struct CSet *)sp->sp_Data;
198 codeset = cset->CodeSet;
199 }
200 *buffer = ami_clipboard_cat_collection(ci, codeset, length);
201 }
202
203 CloseIFF(iffh);
204}
205
206static void gui_set_clipboard(const char *buffer, size_t length,
207 nsclipboard_styles styles[], int n_styles)
208{
209 char *text;
210 struct CSet cset = {0, {0}};
211
212 if(buffer == NULL) return;
213
214 if(!(OpenIFF(iffh, IFFF_WRITE)))
215 {
216 if(!(PushChunk(iffh, ID_FTXT, ID_FORM, IFFSIZE_UNKNOWN)))
217 {
218 if(nsoption_bool(clipboard_write_utf8))
219 {
220 if(!(PushChunk(iffh, 0, ID_CSET, 32)))
221 {
222 cset.CodeSet = 106; // UTF-8
223 WriteChunkBytes(iffh, &cset, 32);
224 PopChunk(iffh);
225 }
226 }
227 }
228 else
229 {
230 PopChunk(iffh);
231 }
232
233 if(!(PushChunk(iffh, 0, ID_CHRS, IFFSIZE_UNKNOWN))) {
234 if(nsoption_bool(clipboard_write_utf8)) {
235 WriteChunkBytes(iffh, buffer, length);
236 } else {
237 if(utf8_to_local_encoding(buffer, length, &text) == NSERROR_OK) {
238 char *p;
239
240 p = text;
241
242 while(*p != '\0') {
243 if(*p == 0xa0) *p = 0x20;
244 p++;
245 }
246 WriteChunkBytes(iffh, text, strlen(text));
248 }
249 }
250
251 PopChunk(iffh);
252 } else {
253 PopChunk(iffh);
254 }
255
256 if(!(PushChunk(iffh, 0, ID_UTF8, IFFSIZE_UNKNOWN))) {
257 WriteChunkBytes(iffh, buffer, length);
258 PopChunk(iffh);
259 } else {
260 PopChunk(iffh);
261 }
262 CloseIFF(iffh);
263 }
264}
265
267{
268 int x;
269 int y;
270 char *utf8text;
271 char *sel;
272 struct IFFHandle *old_iffh = iffh;
274
275 /* NB: 'gwin' is at the drop point, 'g' is where the selection was dragged from.
276 * These may be different if the selection has been dragged between windows. */
277
278 if(!gwin)
279 {
280 ami_gui_beep();
281 return;
282 }
283
284 x = ami_gui2_get_window(gwin)->MouseX;
285 y = ami_gui2_get_window(gwin)->MouseY;
286
287 if(ami_text_box_at_point(gwin, (ULONG *)&x, (ULONG *)&y))
288 {
290
294
296 iffh = old_iffh;
297 }
298 else
299 {
300 x = ami_gui2_get_window(gwin)->MouseX;
301 y = ami_gui2_get_window(gwin)->MouseY;
302
304 {
306 {
307 utf8text = ami_utf8_easy(sel);
309 ami_gui2_get_window(gwin), NULL, STRINGA_TextVal, utf8text, TAG_DONE);
310 free(sel);
311 ami_utf8_free(utf8text);
312 }
313 }
315 {
317 {
318 utf8text = ami_utf8_easy(sel);
320 ami_gui2_get_window(gwin), NULL, STRINGA_TextVal, utf8text, TAG_DONE);
321 free(sel);
322 ami_utf8_free(utf8text);
323 }
324 }
325 else
326 {
327 ami_gui_beep();
328 }
329 }
330}
331
332bool ami_easy_clipboard(const char *text)
333{
334 gui_set_clipboard(text, strlen(text), NULL, 0);
335 return true;
336}
337
339{
340 Object *dto = NULL;
341
343 {
344 DoDTMethod(dto,NULL,NULL,DTM_COPY,NULL);
345 DisposeDTObject(dto);
346 }
347 return true;
348}
349
350#ifdef WITH_NS_SVG
351bool ami_easy_clipboard_svg(struct hlcache_handle *c)
352{
353 const uint8_t *source_data;
354 size_t source_size;
355
356 if (ami_mime_compare(c, "svg") == false) {
357 return false;
358 }
359 source_data = content_get_source_data(c, &source_size);
360 if (source_data == NULL) {
361 return false;
362 }
363
364 if (!(OpenIFF(iffh,IFFF_WRITE))) {
365 ami_svg_to_dr2d(iffh,
366 (const char *)source_data,
367 source_size,
369 CloseIFF(iffh);
370 }
371
372 return true;
373}
374#endif
375
378 .set = gui_set_clipboard,
379};
380
static void gui_set_clipboard(const char *buffer, size_t length, nsclipboard_styles styles[], int n_styles)
Definition: clipboard.c:206
void ami_clipboard_free(void)
Definition: clipboard.c:82
static struct IFFHandle * iffh
Definition: clipboard.c:53
static void gui_get_clipboard(char **buffer, size_t *length)
Definition: clipboard.c:177
bool ami_easy_clipboard(const char *text)
Definition: clipboard.c:332
void ami_drag_selection(struct gui_window *g)
Definition: clipboard.c:266
void ami_clipboard_init(void)
Definition: clipboard.c:70
struct gui_clipboard_table * amiga_clipboard_table
Definition: clipboard.c:381
static struct gui_clipboard_table clipboard_table
Definition: clipboard.c:376
static struct IFFHandle * ami_clipboard_init_internal(int unit)
Definition: clipboard.c:55
void gui_start_selection(struct gui_window *g)
Definition: clipboard.c:87
static char * ami_clipboard_cat_collection(struct CollectionItem *ci, LONG codeset, size_t *text_length)
Definition: clipboard.c:100
bool ami_easy_clipboard_bitmap(struct bitmap *bitmap)
Definition: clipboard.c:338
static void ami_clipboard_free_internal(struct IFFHandle *iffhandle)
Definition: clipboard.c:75
#define ID_UTF8
Definition: clipboard.c:51
bool ami_mime_compare(struct hlcache_handle *c, const char *type)
Compare the MIME type of an hlcache_handle to a DefIcons type.
Definition: filetype.c:614
struct Window * ami_gui_get_window(struct gui_window *gw)
Get window from gui_window.
Definition: gui.c:578
bool ami_text_box_at_point(struct gui_window_2 *gwin, ULONG *restrict x, ULONG *restrict y)
Definition: gui.c:6194
void * ami_window_at_pointer(int type)
undocumented, or internal, or documented elsewhere
Definition: gui.c:684
struct Menu * ami_gui_get_menu(struct gui_window *gw)
Get imenu from gui_window.
Definition: gui.c:584
struct browser_window * ami_gui2_get_browser_window(struct gui_window_2 *gwin)
Get browser window from gui_window_2.
Definition: gui.c:427
Object * ami_gui2_get_object(struct gui_window_2 *gwin, int object_type)
Get object from gui_window.
Definition: gui.c:536
void ami_gui_beep(void)
Beep.
Definition: gui.c:416
struct Window * ami_gui2_get_window(struct gui_window_2 *gwin)
Get window from gui_window_2.
Definition: gui.c:572
struct browser_window * ami_gui_get_browser_window(struct gui_window *gw)
Get browser window from gui_window.
Definition: gui.c:421
BOOL ami_gadget_hit(Object *obj, int x, int y)
Definition: gui.c:6221
@ AMI_GAD_URL
Definition: gui.h:45
@ AMI_GAD_SEARCH
Definition: gui.h:46
Browser window creation and manipulation interface.
void browser_window_mouse_click(struct browser_window *bw, browser_mouse_state mouse, int x, int y)
Handle mouse clicks in a browser window.
@ BW_EDITOR_CAN_CUT
Selection not read-only.
char * browser_window_get_selection(struct browser_window *bw)
Get the current selection from a root browser window, ownership passed to caller, who must free() it.
browser_editor_flags browser_window_get_editor_flags(struct browser_window *bw)
Check whether browser window can accept a cut/copy/paste, or has a selection that could be saved.
static osspriteop_area * buffer
The buffer characteristics.
Definition: buffer.c:55
@ NSERROR_OK
No error.
Definition: errors.h:30
Object * ami_datatype_object_from_bitmap(struct bitmap *bitmap)
Definition: bitmap.c:369
@ AMINS_WINDOW
Definition: object.h:28
void ami_utf8_free(char *ptr)
Definition: utf8.c:104
nserror utf8_to_local_encoding(const char *string, size_t len, char **result)
Definition: utf8.c:89
char * ami_utf8_easy(const char *string)
Definition: utf8.c:109
nserror utf8_from_local_encoding(const char *string, size_t len, char **result)
Definition: utf8.c:80
void ami_gui_menu_set_disabled(struct Window *win, struct Menu *menu, int item, bool disable)
Set disabled state of a menu item almost generic, but not quite.
Definition: gui_menu.c:679
@ M_CUT
Definition: gui_menu.h:55
@ M_CLEAR
Definition: gui_menu.h:60
@ M_COPY
Definition: gui_menu.h:56
#define ID_CSET
Definition: iff_cset.h:31
Interface to platform-specific clipboard operations.
Public content interface.
struct nsurl * hlcache_handle_get_url(const struct hlcache_handle *handle)
Retrieve the URL associated with a high level cache handle.
const uint8_t * content_get_source_data(struct hlcache_handle *h, size_t *size)
Retrieve source of content.
Definition: content.c:1209
@ BROWSER_MOUSE_PRESS_1
primary button pressed
Definition: mouse.h:59
Target independent plotting interface.
Interface to platform-specific graphical user interface window operations.
Interface to key press operations.
@ NS_KEY_PASTE
Definition: keypress.h:43
@ NS_KEY_COPY_SELECTION
Definition: keypress.h:33
bool browser_window_key_press(struct browser_window *bw, uint32_t key)
Handle key presses in a browser window.
Definition: textinput.c:107
NetSurf URL handling (interface).
const char * nsurl_access(const nsurl *url)
Access a NetSurf URL object as a string.
ULONG RefreshSetGadgetAttrs(struct Gadget *g, struct Window *w, struct Requester *r, Tag tag1,...)
Definition: os3support.c:429
#define ObtainCharsetInfo(A, B, C)
Definition: os3support.h:154
Interface to utility string handling.
Definition: iff_cset.h:25
LONG CodeSet
Definition: iff_cset.h:26
RISC OS wimp toolkit bitmap.
Definition: bitmap.c:68
function table for clipboard operations.
Definition: clipboard.h:42
void(* get)(char **buffer, size_t *length)
Core asks front end for clipboard contents.
Definition: clipboard.h:49
first entry in window list
Definition: gui.c:298
High-level cache handle.
Definition: hlcache.c:66
Option reading and saving interface.
#define nsoption_bool(OPTION)
Get the value of a boolean option.
Definition: nsoption.h:304
nserror utf8_from_enc(const char *string, const char *encname, size_t len, char **result, size_t *result_len)
Convert a string in the named encoding into a UTF-8 string.
Definition: utf8.c:321
UTF-8 manipulation functions (interface).
static nserror text(const struct redraw_context *ctx, const struct plot_font_style *fstyle, int x, int y, const char *text, size_t length)
Text plotting.
Definition: plot.c:978