NetSurf
textselection.c
Go to the documentation of this file.
1/*
2 * Copyright 2005 Adrian Lees <adrianl@users.sourceforge.net>
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/**
20 * \file
21 * RISC OS text selection implementation.
22 */
23
24#include <assert.h>
25#include <stdio.h>
26#include <string.h>
27#include <stdlib.h>
28#include <oslib/osfile.h>
29#include <oslib/wimp.h>
30
31#include "utils/log.h"
32#include "utils/utf8.h"
33#include "utils/utils.h"
34#include "netsurf/clipboard.h"
35#include "netsurf/window.h"
37
38#include "riscos/gui.h"
39#include "riscos/window.h"
40#include "riscos/menus.h"
41#include "riscos/message.h"
42#include "riscos/mouse.h"
43#include "riscos/save.h"
45#include "riscos/ucstables.h"
46
47
48#ifndef wimp_DRAG_CLAIM_SUPPRESS_DRAGBOX
49#define wimp_DRAG_CLAIM_SUPPRESS_DRAGBOX ((wimp_drag_claim_flags) 0x2u)
50#endif
51
52
53/** Receive of Dragging message has claimed it */
54static bool dragging_claimed = false;
55static wimp_t dragging_claimant;
56static os_box dragging_box = { -34, -34, 34, 34 }; /* \todo - size properly */
57static wimp_drag_claim_flags last_claim_flags = 0;
59
60static bool drag_claimed = false;
61
62static bool owns_clipboard = false;
63static bool owns_caret_and_selection = false;
64
65/* Current clipboard contents if we own the clipboard
66 * Current paste buffer if we don't
67 */
68static char *clipboard = NULL;
69static size_t clip_length = 0;
70
71/* Paste context */
73static void *paste_cb_pw = NULL;
74static int paste_prev_message = 0;
75
76static void ro_gui_selection_drag_end(wimp_dragged *drag, void *g);
77static void ro_gui_discard_clipboard_contents(void);
78static void ro_gui_dragging_bounced(wimp_message *message);
79
80
81/**
82 * Start drag-selecting text within a browser window (RO-dependent part)
83 *
84 * \param g gui window
85 */
86
88{
89 wimp_full_message_claim_entity msg;
90 wimp_auto_scroll_info scroll;
91 wimp_window_state state;
92 wimp_drag drag;
93 os_error *error;
94
95 NSLOG(netsurf, INFO, "starting text_selection drag");
96
97 state.w = g->window;
98 error = xwimp_get_window_state(&state);
99 if (error) {
100 NSLOG(netsurf, INFO, "xwimp_get_window_state 0x%x: %s",
101 error->errnum, error->errmess);
102 ro_warn_user("WimpError", error->errmess);
103 return;
104 }
105
106 /* claim caret and selection */
107 msg.size = sizeof(msg);
108 msg.your_ref = 0;
109 msg.action = message_CLAIM_ENTITY;
110 msg.flags = wimp_CLAIM_CARET_OR_SELECTION;
111
112 error = xwimp_send_message(wimp_USER_MESSAGE,
113 (wimp_message*)&msg, wimp_BROADCAST);
114 if (error) {
115 NSLOG(netsurf, INFO, "xwimp_send_message: 0x%x: %s",
116 error->errnum, error->errmess);
117 ro_warn_user("WimpError", error->errmess);
118 }
120
121 scroll.w = g->window;
122 scroll.pause_zone_sizes.x0 = 80;
123 scroll.pause_zone_sizes.y0 = 80;
124 scroll.pause_zone_sizes.x1 = 80;
125 scroll.pause_zone_sizes.y1 = 80;
126 scroll.pause_duration = 0;
127 scroll.state_change = (void *)0;
128 error = xwimp_auto_scroll(wimp_AUTO_SCROLL_ENABLE_VERTICAL |
129 wimp_AUTO_SCROLL_ENABLE_HORIZONTAL,
130 &scroll, 0);
131 if (error)
132 NSLOG(netsurf, INFO, "xwimp_auto_scroll: 0x%x: %s",
133 error->errnum, error->errmess);
134
136 NULL, g);
137
138 drag.type = wimp_DRAG_USER_POINT;
139 /* Don't constrain mouse pointer during drags */
140 drag.bbox.x0 = -16384;
141 drag.bbox.y0 = -16384;
142 drag.bbox.x1 = 16384;
143 drag.bbox.y1 = 16384;
144
145 error = xwimp_drag_box(&drag);
146 if (error) {
147 NSLOG(netsurf, INFO, "xwimp_drag_box: 0x%x : %s",
148 error->errnum, error->errmess);
149 ro_warn_user("WimpError", error->errmess);
150 }
152}
153
154
155/**
156 * End of text selection drag operation
157 *
158 * \param *drag position of pointer at conclusion of drag
159 * \param *data gui window pointer.
160 */
161
162static void ro_gui_selection_drag_end(wimp_dragged *drag, void *data)
163{
164 wimp_auto_scroll_info scroll;
165 wimp_pointer pointer;
166 os_error *error;
167 os_coord pos;
168 struct gui_window *g = (struct gui_window *) data;
169
170 scroll.w = g->window;
171 error = xwimp_auto_scroll(0, &scroll, 0);
172 if (error)
173 NSLOG(netsurf, INFO, "xwimp_auto_scroll: 0x%x: %s",
174 error->errnum, error->errmess);
175
176 error = xwimp_drag_box((wimp_drag*)-1);
177 if (error) {
178 NSLOG(netsurf, INFO, "xwimp_drag_box: 0x%x : %s",
179 error->errnum, error->errmess);
180 ro_warn_user("WimpError", error->errmess);
181 }
182
183 error = xwimp_get_pointer_info(&pointer);
184 if (error) {
185 NSLOG(netsurf, INFO, "xwimp_get_pointer_info 0x%x : %s",
186 error->errnum, error->errmess);
187 ro_warn_user("WimpError", error->errmess);
188 return;
189 }
190
191 if (ro_gui_window_to_window_pos(g, drag->final.x0, drag->final.y0, &pos)) {
192 browser_window_mouse_track(g->bw, 0, pos.x, pos.y);
193 }
194}
195
196/**
197 * Core tells front end to put given text in clipboard
198 *
199 * \param buffer UTF-8 text, owned by core
200 * \param length Byte length of UTF-8 text in buffer
201 * \param styles Array of styles given to text runs, owned by core, or NULL
202 * \param n_styles Number of text run styles in array
203 */
204static void gui_set_clipboard(const char *buffer, size_t length,
205 nsclipboard_styles styles[], int n_styles)
206{
207 char *new_cb;
208
209 if (length == 0)
210 return;
211
212 new_cb = malloc(length);
213 if (new_cb == NULL)
214 return;
215
216 memcpy(new_cb, buffer, length);
217
218 /* Replace existing clipboard contents */
219 free(clipboard);
220 clipboard = new_cb;
221 clip_length = length;
222
223 if (!owns_clipboard) {
224 /* Tell RO we now own clipboard */
225 wimp_full_message_claim_entity msg;
226 os_error *error;
227
228 NSLOG(netsurf, INFO, "claiming clipboard");
229
230 msg.size = sizeof(msg);
231 msg.your_ref = 0;
232 msg.action = message_CLAIM_ENTITY;
233 msg.flags = wimp_CLAIM_CLIPBOARD;
234
235 error = xwimp_send_message(wimp_USER_MESSAGE,
236 (wimp_message*)&msg, wimp_BROADCAST);
237 if (error) {
238 NSLOG(netsurf, INFO, "xwimp_send_message: 0x%x: %s",
239 error->errnum, error->errmess);
240 ro_warn_user("WimpError", error->errmess);
241 }
242 owns_clipboard = true;
243 }
244
245 NSLOG(netsurf, INFO, "clipboard now holds %zd bytes", clip_length);
246}
247
248
249/**
250 * Core asks front end for clipboard contents.
251 *
252 * \param buffer UTF-8 text, allocated by front end, ownership yielded to core
253 * \param length Byte length of UTF-8 text in buffer
254 */
255static void gui_get_clipboard(char **buffer, size_t *length)
256{
257 *buffer = NULL;
258 *length = 0;
259
260 if (clip_length > 0) {
261 char *cb = malloc(clip_length);
262 if (cb != NULL) {
263 memcpy(cb, clipboard, clip_length);
264 *buffer = cb;
265 *length = clip_length;
266 }
267 }
268}
269
270
271/**
272 * Discard the current contents of the clipboard, if any, releasing the
273 * memory it uses.
274 */
275
277{
278 free(clipboard);
279 clipboard = NULL;
280 clip_length = 0;
281}
282
283
285{
287 void *pw = paste_cb_pw;
288
289 paste_cb = NULL;
290 paste_cb_pw = NULL;
292
293 cb(pw);
294}
295
296static void ro_gui_selection_prepare_paste_bounced(wimp_message *message)
297{
299}
300
301/**
302 * Prepare to paste data from another application
303 *
304 * \param w Window being pasted into
305 * \param cb Callback to call once preparation is complete
306 * \param pw Private data for callback
307 */
308
311{
312 if (owns_clipboard) {
313 /* We own the clipboard: we're already prepared */
314 cb(pw);
315 } else {
316 /* Someone else owns the clipboard: request its contents */
317 wimp_full_message_data_request msg;
318 bool success;
319
321
322 msg.size = 48; /* There's only one filetype listed. */
323 msg.your_ref = 0;
324 msg.action = message_DATA_REQUEST;
325 msg.w = w;
326 msg.i = -1;
327 msg.pos.x = 0;
328 msg.pos.y = 0;
329 msg.flags = wimp_DATA_REQUEST_CLIPBOARD;
330 msg.file_types[0] = osfile_TYPE_TEXT;
331 msg.file_types[1] = ~0;
332
333 success = ro_message_send_message(wimp_USER_MESSAGE_RECORDED,
334 (wimp_message *) &msg, wimp_BROADCAST,
336 if (success == false) {
337 /* Ensure key is handled, anyway */
338 cb(pw);
339 } else {
340 /* Set up paste context */
341 paste_cb = cb;
342 paste_cb_pw = pw;
343 paste_prev_message = msg.my_ref;
344 }
345 }
346}
347
348/**
349 * Prepare to paste data from another application (step 2)
350 *
351 * \param dataxfer DataSave message
352 * \return True if message was handled, false otherwise
353 */
355 wimp_full_message_data_xfer *dataxfer)
356{
357 bool success;
358
359 /* Ignore messages that aren't for us */
360 if (dataxfer->your_ref == 0 || dataxfer->your_ref != paste_prev_message)
361 return false;
362
363 /* We're done if the paste data isn't text */
364 if (dataxfer->file_type != osfile_TYPE_TEXT) {
366 return true;
367 }
368
369 /* Generate and send DataSaveAck */
370 dataxfer->your_ref = dataxfer->my_ref;
371 dataxfer->size = offsetof(wimp_full_message_data_xfer, file_name) + 16;
372 dataxfer->action = message_DATA_SAVE_ACK;
373 dataxfer->est_size = -1;
374 memcpy(dataxfer->file_name, "<Wimp$Scrap>", SLEN("<Wimp$Scrap>") + 1);
375
376 success = ro_message_send_message(wimp_USER_MESSAGE_RECORDED,
377 (wimp_message *) dataxfer, dataxfer->sender,
379 if (success == false) {
381 } else {
382 paste_prev_message = dataxfer->my_ref;
383 }
384
385 return true;
386}
387
388
389/**
390 * Prepare to paste data from another application (step 3)
391 *
392 * \param dataxfer DataLoad message
393 * \return True if message was handled, false otherwise
394 */
396 wimp_full_message_data_xfer *dataxfer)
397{
398 FILE *fp;
399
400 /* Ignore messages that aren't for us */
401 if (dataxfer->your_ref == 0 || dataxfer->your_ref != paste_prev_message)
402 return false;
403
404 fp = fopen(dataxfer->file_name, "r");
405 if (fp != NULL) {
406 long size;
407 fseek(fp, 0, SEEK_END);
408 size = ftell(fp);
409 fseek(fp, 0, SEEK_SET);
410
411 if (size > 0) {
412 char *local_cb = malloc(size);
413 if (local_cb != NULL) {
414 nserror ret;
415 fread(local_cb, 1, size, fp);
416
417 ret = utf8_from_local_encoding(local_cb, size,
418 &clipboard);
419 if (ret == NSERROR_OK) {
420 clip_length = strlen(clipboard);
421 }
422
423 free(local_cb);
424 }
425 }
426
427 fclose(fp);
428 }
429
430 /* Send DataLoadAck */
431 dataxfer->action = message_DATA_LOAD_ACK;
432 dataxfer->your_ref = dataxfer->my_ref;
433 ro_message_send_message(wimp_USER_MESSAGE,
434 (wimp_message *) dataxfer, dataxfer->sender, NULL);
435
437 return true;
438}
439
440
441/**
442 * Responds to CLAIM_ENTITY message notifying us that the caret
443 * and selection or clipboard have been claimed by another application.
444 *
445 * \param claim CLAIM_ENTITY message
446 */
447
448void ro_gui_selection_claim_entity(wimp_full_message_claim_entity *claim)
449{
450 /* ignore our own broadcasts! */
451 if (claim->sender != task_handle) {
452
453 NSLOG(netsurf, INFO, "%x", claim->flags);
454
455 if (claim->flags & wimp_CLAIM_CARET_OR_SELECTION) {
457 }
458
459 if (claim->flags & wimp_CLAIM_CLIPBOARD) {
461 owns_clipboard = false;
462 }
463 }
464}
465
466
467/**
468 * Responds to DATA_REQUEST message, returning information about the
469 * clipboard contents if we own the clipboard.
470 *
471 * \param req DATA_REQUEST message
472 */
473
474void ro_gui_selection_data_request(wimp_full_message_data_request *req)
475{
476 if (owns_clipboard && clip_length > 0 &&
477 (req->flags & wimp_DATA_REQUEST_CLIPBOARD)) {
478 wimp_full_message_data_xfer message;
479 int size;
480// int i;
481
482// for(i = 0; i < NOF_ELEMENTS(req->file_types); i++) {
483// bits ftype = req->file_types[i];
484// if (ftype == ~0U) break; /* list terminator */
485//
486// NSLOG(netsurf, INFO, "type %x", ftype);
487// i++;
488// }
489
490 /* we can only supply text at the moment, so that's what you're getting! */
491 size = offsetof(wimp_full_message_data_xfer, file_name) + 9;
492 message.size = (size + 3) & ~3;
493 message.your_ref = req->my_ref;
494 message.action = message_DATA_SAVE;
495 message.w = req->w;
496 message.i = req->i;
497 message.pos = req->pos;
498 message.file_type = osfile_TYPE_TEXT;
499 message.est_size = clip_length;
500 memcpy(message.file_name, "TextFile", 9);
501
503 &message, req->sender);
504 }
505}
506
507
508/**
509 * Save the clipboard contents to a file.
510 *
511 * \param path the pathname of the file
512 * \return true iff success, otherwise reporting the error before returning false
513 */
514
516{
517 char *local_cb;
518 nserror ret;
519 os_error *error;
520
521 assert(clip_length > 0 && clipboard);
522
524 if (ret != NSERROR_OK) {
525 ro_warn_user("SaveError", "Could not convert");
526 return false;
527 }
528
529 error = xosfile_save_stamped(path, osfile_TYPE_TEXT,
530 (byte*) local_cb,
531 (byte*) local_cb + strlen(local_cb));
532
533 free(local_cb);
534
535 if (error) {
536 NSLOG(netsurf, INFO, "xosfile_save_stamped: 0x%x: %s",
537 error->errnum, error->errmess);
538 ro_warn_user("SaveError", error->errmess);
539 return false;
540 }
541
542 return true;
543}
544
545
546/**
547 * Handler for Message_Dragging, used to implement auto-scrolling and
548 * ghost caret when a drag is in progress.
549 */
550
551void ro_gui_selection_dragging(wimp_message *message)
552{
553 wimp_full_message_dragging *drag = (wimp_full_message_dragging*)message;
554 struct gui_window *g;
555 os_coord pos;
556
557 /* with autoscrolling, we will probably need to remember the
558 * gui_window and override the drag->w window handle which
559 * could be any window on the desktop */
560 g = ro_gui_window_lookup(drag->w);
561
562 if ((drag->flags & wimp_DRAGGING_TERMINATE_DRAG) || !g) {
563
564 drag_claimed = false;
565 return;
566 }
567
568 if (!ro_gui_window_to_window_pos(g, drag->pos.x, drag->pos.y, &pos))
569 return;
570
571 drag_claimed = false;
572}
573
574
575
576/**
577 * Reset drag-and-drop state when drag completes (DataSave received)
578 */
579
581{
582 drag_claimed = false;
583}
584
585
586/**
587 *
588 */
589
590void ro_gui_selection_drag_claim(wimp_message *message)
591{
592 wimp_full_message_drag_claim *claim = (wimp_full_message_drag_claim*)message;
593
594 dragging_claimant = message->sender;
595 dragging_claimed = true;
596
597 /* have we been asked to remove the drag box/sprite? */
598 if (claim->flags & wimp_DRAG_CLAIM_SUPPRESS_DRAGBOX) {
600 }
601 else {
602 /* \todo - restore it here? */
603 }
604
605 /* do we need to restore the default pointer shape? */
606 if ((last_claim_flags & wimp_DRAG_CLAIM_POINTER_CHANGED) &&
607 !(claim->flags & wimp_DRAG_CLAIM_POINTER_CHANGED)) {
609 }
610
611 last_claim_flags = claim->flags;
612}
613
614
615void ro_gui_selection_send_dragging(wimp_pointer *pointer)
616{
617 wimp_full_message_dragging dragmsg;
618
619 NSLOG(netsurf, INFO, "sending DRAGGING to %p, %d", pointer->w,
620 pointer->i);
621
622 dragmsg.size = offsetof(wimp_full_message_dragging, file_types) + 8;
623 dragmsg.your_ref = 0;
624 dragmsg.action = message_DRAGGING;
625 dragmsg.w = pointer->w;
626 dragmsg.i = pointer->i;
627 dragmsg.pos = pointer->pos;
628/* \todo - this is interesting because it depends upon not just the state of the
629 shift key, but also whether it /can/ be deleted, ie. from text area/input
630 rather than page contents */
631 dragmsg.flags = wimp_DRAGGING_FROM_SELECTION;
632 dragmsg.box = dragging_box;
633 dragmsg.file_types[0] = osfile_TYPE_TEXT;
634 dragmsg.file_types[1] = ~0;
635
636 /* if the message_dragmsg messages have been claimed we must address them
637 to the claimant task, which is not necessarily the task that owns whatever
638 window happens to be under the pointer */
639
640 if (dragging_claimed) {
641 ro_message_send_message(wimp_USER_MESSAGE_RECORDED,
642 (wimp_message*)&dragmsg, dragging_claimant, ro_gui_dragging_bounced);
643 }
644 else {
645 ro_message_send_message_to_window(wimp_USER_MESSAGE_RECORDED,
646 (wimp_message*)&dragmsg, pointer->w, pointer->i,
648 }
649}
650
651
652/**
653 * Our message_DRAGGING message was bounced, ie. the intended recipient does not
654 * support the drag-and-drop protocol or cannot receive the data at the pointer
655 * position.
656 */
657
658void ro_gui_dragging_bounced(wimp_message *message)
659{
660 dragging_claimed = false;
661}
662
665 .set = gui_set_clipboard,
666};
667
void gui_window_set_pointer(struct gui_window *g, gui_pointer_shape shape)
Change mouse pointer shape.
Definition: theme.c:216
Browser window creation and manipulation interface.
void browser_window_mouse_track(struct browser_window *bw, browser_mouse_state mouse, int x, int y)
Handle non-click mouse action in a browser window.
static osspriteop_area * buffer
The buffer characteristics.
Definition: buffer.c:55
nserror
Enumeration of error codes.
Definition: errors.h:29
@ NSERROR_OK
No error.
Definition: errors.h:30
nserror utf8_to_local_encoding(const char *string, size_t len, char **result)
Definition: utf8.c:89
nserror utf8_from_local_encoding(const char *string, size_t len, char **result)
Definition: utf8.c:80
void ro_mouse_drag_start(void(*drag_end)(wimp_dragged *dragged, void *data), void(*drag_track)(wimp_pointer *pointer, void *data), void(*drag_cancel)(void *data), void *data)
Start a drag, providing a function to be called when the Wimp_DragEnd event is received and optionall...
Definition: mouse.c:115
Mouse dragging and tracking support interface for RISC OS.
static bool owns_caret_and_selection
Definition: textselection.c:63
bool ro_gui_save_clipboard(const char *path)
Save the clipboard contents to a file.
static void gui_set_clipboard(const char *buffer, size_t length, nsclipboard_styles styles[], int n_styles)
Core tells front end to put given text in clipboard.
static bool drag_claimed
Definition: textselection.c:60
#define wimp_DRAG_CLAIM_SUPPRESS_DRAGBOX
Definition: textselection.c:49
static wimp_drag_claim_flags last_claim_flags
Definition: textselection.c:57
static char * clipboard
Definition: textselection.c:68
static wimp_t dragging_claimant
Definition: textselection.c:55
static void gui_get_clipboard(char **buffer, size_t *length)
Core asks front end for clipboard contents.
static bool owns_clipboard
Definition: textselection.c:62
static void ro_gui_dragging_bounced(wimp_message *message)
Our message_DRAGGING message was bounced, ie.
static size_t clip_length
Definition: textselection.c:69
static void ro_gui_selection_drag_end(wimp_dragged *drag, void *g)
End of text selection drag operation.
void ro_gui_selection_data_request(wimp_full_message_data_request *req)
Responds to DATA_REQUEST message, returning information about the clipboard contents if we own the cl...
static void * paste_cb_pw
Definition: textselection.c:73
static ro_gui_selection_prepare_paste_cb paste_cb
Definition: textselection.c:72
static void ro_gui_selection_prepare_paste_complete(void)
void ro_gui_selection_claim_entity(wimp_full_message_claim_entity *claim)
Responds to CLAIM_ENTITY message notifying us that the caret and selection or clipboard have been cla...
static void ro_gui_selection_prepare_paste_bounced(wimp_message *message)
static struct gui_clipboard_table clipboard_table
static void ro_gui_discard_clipboard_contents(void)
Discard the current contents of the clipboard, if any, releasing the memory it uses.
struct gui_clipboard_table * riscos_clipboard_table
static struct gui_window * last_start_window
Definition: textselection.c:58
void gui_start_selection(struct gui_window *g)
Start drag-selecting text within a browser window (RO-dependent part)
Definition: textselection.c:87
bool ro_gui_selection_prepare_paste_datasave(wimp_full_message_data_xfer *dataxfer)
Prepare to paste data from another application (step 2)
static bool dragging_claimed
Receive of Dragging message has claimed it.
Definition: textselection.c:54
void ro_gui_selection_drag_reset(void)
Reset drag-and-drop state when drag completes (DataSave received)
void ro_gui_selection_prepare_paste(wimp_w w, ro_gui_selection_prepare_paste_cb cb, void *pw)
Prepare to paste data from another application.
static os_box dragging_box
Definition: textselection.c:56
void ro_gui_selection_dragging(wimp_message *message)
Handler for Message_Dragging, used to implement auto-scrolling and ghost caret when a drag is in prog...
void ro_gui_selection_send_dragging(wimp_pointer *pointer)
bool ro_gui_selection_prepare_paste_dataload(wimp_full_message_data_xfer *dataxfer)
Prepare to paste data from another application (step 3)
static int paste_prev_message
Definition: textselection.c:74
void ro_gui_selection_drag_claim(wimp_message *message)
Text selection import/export (interface).
void(* ro_gui_selection_prepare_paste_cb)(void *pw)
Definition: textselection.h:32
Browser window handling (interface).
Interface to platform-specific clipboard operations.
@ GUI_POINTER_DEFAULT
Definition: mouse.h:113
Interface to platform-specific graphical user interface window operations.
@ GUI_SAVE_CLIPBOARD_CONTENTS
Definition: window.h:53
#define NSLOG(catname, level, logmsg, args...)
Definition: log.h:116
bool ro_message_send_message(wimp_event_no event, wimp_message *message, wimp_t task, void(*callback)(wimp_message *message))
Sends a message and registers a return route for a bounce.
Definition: message.c:57
bool ro_message_send_message_to_window(wimp_event_no event, wimp_message *message, wimp_w to_w, wimp_i to_i, void(*callback)(wimp_message *message), wimp_t *to_t)
Sends a message and registers a return route for a bounce.
Definition: message.c:94
Automated RISC OS message routing (interface).
wimp_t task_handle
RISC OS wimp task handle.
Definition: gui.c:116
nserror ro_warn_user(const char *warning, const char *detail)
Display a warning for a serious problem (eg memory exhaustion).
Definition: gui.c:2077
File/object/selection saving (Interface).
bool ro_gui_window_to_window_pos(struct gui_window *g, int x, int y, os_coord *pos)
Convert x,y screen co-ordinates into window co-ordinates.
Definition: window.c:4855
void ro_gui_window_mouse_at(wimp_pointer *pointer, void *data)
Handle pointer movements in a browser window.
Definition: window.c:4513
struct gui_window * ro_gui_window_lookup(wimp_w window)
Convert a RISC OS window handle to a gui_window.
Definition: window.c:4823
void ro_gui_send_datasave(gui_save_type save_type, wimp_full_message_data_xfer *message, wimp_t to)
Send DataSave message on behalf of clipboard code and remember that it's the clipboard contents we're...
Definition: save.c:1397
void ro_gui_drag_box_cancel(void)
Definition: save.c:1364
Interface to utility string handling.
int x
Window dimensions.
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
int state
Definition: window.cpp:73
struct fbtk_widget_s * window
Definition: gui.h:33
struct browser_window * bw
The 'content' window that is rendered in the gui_window.
Definition: gui.c:316
UCS conversion tables (interface) This is only used if nothing claims Service_International,...
UTF-8 manipulation functions (interface).
Interface to a number of general purpose functionality.
#define SLEN(x)
Calculate length of constant C string.
Definition: utils.h:88
static nserror path(const struct redraw_context *ctx, const plot_style_t *pstyle, const float *p, unsigned int n, const float transform[6])
Plots a path.
Definition: plot.c:821