summaryrefslogtreecommitdiff
path: root/riscos/textselection.c
diff options
context:
space:
mode:
Diffstat (limited to 'riscos/textselection.c')
-rw-r--r--riscos/textselection.c657
1 files changed, 0 insertions, 657 deletions
diff --git a/riscos/textselection.c b/riscos/textselection.c
deleted file mode 100644
index 718171db0..000000000
--- a/riscos/textselection.c
+++ /dev/null
@@ -1,657 +0,0 @@
-/*
- * Copyright 2005 Adrian Lees <adrianl@users.sourceforge.net>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-/** \file
- * Text selection code (platform-dependent implementation)
- */
-
-#include <assert.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <oslib/osfile.h>
-#include <oslib/wimp.h>
-
-#include "utils/log.h"
-#include "utils/utf8.h"
-#include "utils/utils.h"
-#include "content/hlcache.h"
-#include "desktop/gui_clipboard.h"
-#include "desktop/gui_window.h"
-#include "desktop/textinput.h"
-#include "desktop/browser.h"
-
-#include "riscos/gui.h"
-#include "riscos/menus.h"
-#include "riscos/message.h"
-#include "riscos/mouse.h"
-#include "riscos/save.h"
-#include "riscos/textselection.h"
-#include "riscos/ucstables.h"
-
-
-#ifndef wimp_DRAG_CLAIM_SUPPRESS_DRAGBOX
-#define wimp_DRAG_CLAIM_SUPPRESS_DRAGBOX ((wimp_drag_claim_flags) 0x2u)
-#endif
-
-
-/** Receive of Dragging message has claimed it */
-static bool dragging_claimed = false;
-static wimp_t dragging_claimant;
-static os_box dragging_box = { -34, -34, 34, 34 }; /* \todo - size properly */
-static wimp_drag_claim_flags last_claim_flags = 0;
-static struct gui_window *last_start_window;
-
-static bool drag_claimed = false;
-
-static bool owns_clipboard = false;
-static bool owns_caret_and_selection = false;
-
-/* Current clipboard contents if we own the clipboard
- * Current paste buffer if we don't
- */
-static char *clipboard = NULL;
-static size_t clip_length = 0;
-
-/* Paste context */
-static ro_gui_selection_prepare_paste_cb paste_cb = NULL;
-static void *paste_cb_pw = NULL;
-static int paste_prev_message = 0;
-
-static void ro_gui_selection_drag_end(wimp_dragged *drag, void *g);
-static void ro_gui_discard_clipboard_contents(void);
-static void ro_gui_dragging_bounced(wimp_message *message);
-
-
-/**
- * Start drag-selecting text within a browser window (RO-dependent part)
- *
- * \param g gui window
- */
-
-void gui_start_selection(struct gui_window *g)
-{
- wimp_full_message_claim_entity msg;
- wimp_auto_scroll_info scroll;
- wimp_window_state state;
- wimp_drag drag;
- os_error *error;
-
- LOG("starting text_selection drag");
-
- state.w = g->window;
- error = xwimp_get_window_state(&state);
- if (error) {
- LOG("xwimp_get_window_state 0x%x: %s", error->errnum, error->errmess);
- ro_warn_user("WimpError", error->errmess);
- return;
- }
-
- /* claim caret and selection */
- msg.size = sizeof(msg);
- msg.your_ref = 0;
- msg.action = message_CLAIM_ENTITY;
- msg.flags = wimp_CLAIM_CARET_OR_SELECTION;
-
- error = xwimp_send_message(wimp_USER_MESSAGE,
- (wimp_message*)&msg, wimp_BROADCAST);
- if (error) {
- LOG("xwimp_send_message: 0x%x: %s", error->errnum, error->errmess);
- ro_warn_user("WimpError", error->errmess);
- }
- owns_caret_and_selection = true;
-
- scroll.w = g->window;
- scroll.pause_zone_sizes.x0 = 80;
- scroll.pause_zone_sizes.y0 = 80;
- scroll.pause_zone_sizes.x1 = 80;
- scroll.pause_zone_sizes.y1 = 80;
- scroll.pause_duration = 0;
- scroll.state_change = (void *)0;
- error = xwimp_auto_scroll(wimp_AUTO_SCROLL_ENABLE_VERTICAL |
- wimp_AUTO_SCROLL_ENABLE_HORIZONTAL,
- &scroll, 0);
- if (error)
- LOG("xwimp_auto_scroll: 0x%x: %s", error->errnum, error->errmess);
-
- ro_mouse_drag_start(ro_gui_selection_drag_end, ro_gui_window_mouse_at,
- NULL, g);
-
- drag.type = wimp_DRAG_USER_POINT;
- /* Don't constrain mouse pointer during drags */
- drag.bbox.x0 = -16384;
- drag.bbox.y0 = -16384;
- drag.bbox.x1 = 16384;
- drag.bbox.y1 = 16384;
-
- error = xwimp_drag_box(&drag);
- if (error) {
- LOG("xwimp_drag_box: 0x%x : %s", error->errnum, error->errmess);
- ro_warn_user("WimpError", error->errmess);
- }
- last_start_window = g;
-}
-
-
-/**
- * End of text selection drag operation
- *
- * \param *drag position of pointer at conclusion of drag
- * \param *data gui window pointer.
- */
-
-static void ro_gui_selection_drag_end(wimp_dragged *drag, void *data)
-{
- wimp_auto_scroll_info scroll;
- wimp_pointer pointer;
- os_error *error;
- os_coord pos;
- struct gui_window *g = (struct gui_window *) data;
-
- scroll.w = g->window;
- error = xwimp_auto_scroll(0, &scroll, 0);
- if (error)
- LOG("xwimp_auto_scroll: 0x%x: %s", error->errnum, error->errmess);
-
- error = xwimp_drag_box((wimp_drag*)-1);
- if (error) {
- LOG("xwimp_drag_box: 0x%x : %s", error->errnum, error->errmess);
- ro_warn_user("WimpError", error->errmess);
- }
-
- error = xwimp_get_pointer_info(&pointer);
- if (error) {
- LOG("xwimp_get_pointer_info 0x%x : %s", error->errnum, error->errmess);
- ro_warn_user("WimpError", error->errmess);
- return;
- }
-
- if (ro_gui_window_to_window_pos(g, drag->final.x0, drag->final.y0, &pos))
- browser_window_mouse_track(g->bw, 0, pos.x, pos.y);
-}
-
-/**
- * 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
- */
-static void gui_set_clipboard(const char *buffer, size_t length,
- nsclipboard_styles styles[], int n_styles)
-{
- char *new_cb;
-
- if (length == 0)
- return;
-
- new_cb = malloc(length);
- if (new_cb == NULL)
- return;
-
- memcpy(new_cb, buffer, length);
-
- /* Replace existing clipboard contents */
- free(clipboard);
- clipboard = new_cb;
- clip_length = length;
-
- if (!owns_clipboard) {
- /* Tell RO we now own clipboard */
- wimp_full_message_claim_entity msg;
- os_error *error;
-
- LOG("claiming clipboard");
-
- msg.size = sizeof(msg);
- msg.your_ref = 0;
- msg.action = message_CLAIM_ENTITY;
- msg.flags = wimp_CLAIM_CLIPBOARD;
-
- error = xwimp_send_message(wimp_USER_MESSAGE,
- (wimp_message*)&msg, wimp_BROADCAST);
- if (error) {
- LOG("xwimp_send_message: 0x%x: %s", error->errnum, error->errmess);
- ro_warn_user("WimpError", error->errmess);
- }
- owns_clipboard = true;
- }
-
- LOG("clipboard now holds %zd bytes", clip_length);
-}
-
-
-/**
- * Core asks front end for clipboard contents.
- *
- * \param buffer UTF-8 text, allocated by front end, ownership yielded to core
- * \param length Byte length of UTF-8 text in buffer
- */
-static void gui_get_clipboard(char **buffer, size_t *length)
-{
- *buffer = NULL;
- *length = 0;
-
- if (clip_length > 0) {
- char *cb = malloc(clip_length);
- if (cb != NULL) {
- memcpy(cb, clipboard, clip_length);
- *buffer = cb;
- *length = clip_length;
- }
- }
-}
-
-
-/**
- * Discard the current contents of the clipboard, if any, releasing the
- * memory it uses.
- */
-
-void ro_gui_discard_clipboard_contents(void)
-{
- free(clipboard);
- clipboard = NULL;
- clip_length = 0;
-}
-
-
-static void ro_gui_selection_prepare_paste_complete(void)
-{
- ro_gui_selection_prepare_paste_cb cb = paste_cb;
- void *pw = paste_cb_pw;
-
- paste_cb = NULL;
- paste_cb_pw = NULL;
- paste_prev_message = 0;
-
- cb(pw);
-}
-
-static void ro_gui_selection_prepare_paste_bounced(wimp_message *message)
-{
- ro_gui_selection_prepare_paste_complete();
-}
-
-/**
- * Prepare to paste data from another application
- *
- * \param w Window being pasted into
- * \param cb Callback to call once preparation is complete
- * \param pw Private data for callback
- */
-
-void ro_gui_selection_prepare_paste(wimp_w w,
- ro_gui_selection_prepare_paste_cb cb, void *pw)
-{
- if (owns_clipboard) {
- /* We own the clipboard: we're already prepared */
- cb(pw);
- } else {
- /* Someone else owns the clipboard: request its contents */
- wimp_full_message_data_request msg;
- bool success;
-
- ro_gui_discard_clipboard_contents();
-
- msg.size = 48; /* There's only one filetype listed. */
- msg.your_ref = 0;
- msg.action = message_DATA_REQUEST;
- msg.w = w;
- msg.i = -1;
- msg.pos.x = 0;
- msg.pos.y = 0;
- msg.flags = wimp_DATA_REQUEST_CLIPBOARD;
- msg.file_types[0] = osfile_TYPE_TEXT;
- msg.file_types[1] = ~0;
-
- success = ro_message_send_message(wimp_USER_MESSAGE_RECORDED,
- (wimp_message *) &msg, wimp_BROADCAST,
- ro_gui_selection_prepare_paste_bounced);
- if (success == false) {
- /* Ensure key is handled, anyway */
- cb(pw);
- } else {
- /* Set up paste context */
- paste_cb = cb;
- paste_cb_pw = pw;
- paste_prev_message = msg.my_ref;
- }
- }
-}
-
-/**
- * Prepare to paste data from another application (step 2)
- *
- * \param dataxfer DataSave message
- * \return True if message was handled, false otherwise
- */
-bool ro_gui_selection_prepare_paste_datasave(
- wimp_full_message_data_xfer *dataxfer)
-{
- bool success;
-
- /* Ignore messages that aren't for us */
- if (dataxfer->your_ref == 0 || dataxfer->your_ref != paste_prev_message)
- return false;
-
- /* We're done if the paste data isn't text */
- if (dataxfer->file_type != osfile_TYPE_TEXT) {
- ro_gui_selection_prepare_paste_complete();
- return true;
- }
-
- /* Generate and send DataSaveAck */
- dataxfer->your_ref = dataxfer->my_ref;
- dataxfer->size = offsetof(wimp_full_message_data_xfer, file_name) + 16;
- dataxfer->action = message_DATA_SAVE_ACK;
- dataxfer->est_size = -1;
- memcpy(dataxfer->file_name, "<Wimp$Scrap>", SLEN("<Wimp$Scrap>") + 1);
-
- success = ro_message_send_message(wimp_USER_MESSAGE_RECORDED,
- (wimp_message *) dataxfer, dataxfer->sender,
- ro_gui_selection_prepare_paste_bounced);
- if (success == false) {
- ro_gui_selection_prepare_paste_complete();
- } else {
- paste_prev_message = dataxfer->my_ref;
- }
-
- return true;
-}
-
-
-/**
- * Prepare to paste data from another application (step 3)
- *
- * \param dataxfer DataLoad message
- * \return True if message was handled, false otherwise
- */
-bool ro_gui_selection_prepare_paste_dataload(
- wimp_full_message_data_xfer *dataxfer)
-{
- FILE *fp;
-
- /* Ignore messages that aren't for us */
- if (dataxfer->your_ref == 0 || dataxfer->your_ref != paste_prev_message)
- return false;
-
- fp = fopen(dataxfer->file_name, "r");
- if (fp != NULL) {
- long size;
- fseek(fp, 0, SEEK_END);
- size = ftell(fp);
- fseek(fp, 0, SEEK_SET);
-
- if (size > 0) {
- char *local_cb = malloc(size);
- if (local_cb != NULL) {
- nserror ret;
- fread(local_cb, 1, size, fp);
-
- ret = utf8_from_local_encoding(local_cb, size,
- &clipboard);
- if (ret == NSERROR_OK) {
- clip_length = strlen(clipboard);
- }
-
- free(local_cb);
- }
- }
-
- fclose(fp);
- }
-
- /* Send DataLoadAck */
- dataxfer->action = message_DATA_LOAD_ACK;
- dataxfer->your_ref = dataxfer->my_ref;
- ro_message_send_message(wimp_USER_MESSAGE,
- (wimp_message *) dataxfer, dataxfer->sender, NULL);
-
- ro_gui_selection_prepare_paste_complete();
- return true;
-}
-
-
-/**
- * Responds to CLAIM_ENTITY message notifying us that the caret
- * and selection or clipboard have been claimed by another application.
- *
- * \param claim CLAIM_ENTITY message
- */
-
-void ro_gui_selection_claim_entity(wimp_full_message_claim_entity *claim)
-{
- /* ignore our own broadcasts! */
- if (claim->sender != task_handle) {
-
- LOG("%x", claim->flags);
-
- if (claim->flags & wimp_CLAIM_CARET_OR_SELECTION) {
- owns_caret_and_selection = false;
- }
-
- if (claim->flags & wimp_CLAIM_CLIPBOARD) {
- ro_gui_discard_clipboard_contents();
- owns_clipboard = false;
- }
- }
-}
-
-
-/**
- * Responds to DATA_REQUEST message, returning information about the
- * clipboard contents if we own the clipboard.
- *
- * \param req DATA_REQUEST message
- */
-
-void ro_gui_selection_data_request(wimp_full_message_data_request *req)
-{
- if (owns_clipboard && clip_length > 0 &&
- (req->flags & wimp_DATA_REQUEST_CLIPBOARD)) {
- wimp_full_message_data_xfer message;
- int size;
-// int i;
-
-// for(i = 0; i < NOF_ELEMENTS(req->file_types); i++) {
-// bits ftype = req->file_types[i];
-// if (ftype == ~0U) break; /* list terminator */
-//
-// LOG("type %x", ftype);
-// i++;
-// }
-
- /* we can only supply text at the moment, so that's what you're getting! */
- size = offsetof(wimp_full_message_data_xfer, file_name) + 9;
- message.size = (size + 3) & ~3;
- message.your_ref = req->my_ref;
- message.action = message_DATA_SAVE;
- message.w = req->w;
- message.i = req->i;
- message.pos = req->pos;
- message.file_type = osfile_TYPE_TEXT;
- message.est_size = clip_length;
- memcpy(message.file_name, "TextFile", 9);
-
- ro_gui_send_datasave(GUI_SAVE_CLIPBOARD_CONTENTS,
- &message, req->sender);
- }
-}
-
-
-/**
- * Save the clipboard contents to a file.
- *
- * \param path the pathname of the file
- * \return true iff success, otherwise reporting the error before returning false
- */
-
-bool ro_gui_save_clipboard(const char *path)
-{
- char *local_cb;
- nserror ret;
- os_error *error;
-
- assert(clip_length > 0 && clipboard);
-
- ret = utf8_to_local_encoding(clipboard, clip_length, &local_cb);
- if (ret != NSERROR_OK) {
- ro_warn_user("SaveError", "Could not convert");
- return false;
- }
-
- error = xosfile_save_stamped(path, osfile_TYPE_TEXT,
- (byte*) local_cb,
- (byte*) local_cb + strlen(local_cb));
-
- free(local_cb);
-
- if (error) {
- LOG("xosfile_save_stamped: 0x%x: %s", error->errnum, error->errmess);
- ro_warn_user("SaveError", error->errmess);
- return false;
- }
-
- return true;
-}
-
-
-/**
- * Handler for Message_Dragging, used to implement auto-scrolling and
- * ghost caret when a drag is in progress.
- */
-
-void ro_gui_selection_dragging(wimp_message *message)
-{
- wimp_full_message_dragging *drag = (wimp_full_message_dragging*)message;
- struct gui_window *g;
- os_coord pos;
-
- /* with autoscrolling, we will probably need to remember the
- * gui_window and override the drag->w window handle which
- * could be any window on the desktop */
- g = ro_gui_window_lookup(drag->w);
-
- if ((drag->flags & wimp_DRAGGING_TERMINATE_DRAG) || !g) {
-
- drag_claimed = false;
- return;
- }
-
- if (!ro_gui_window_to_window_pos(g, drag->pos.x, drag->pos.y, &pos))
- return;
-
- drag_claimed = false;
-}
-
-
-
-/**
- * Reset drag-and-drop state when drag completes (DataSave received)
- */
-
-void ro_gui_selection_drag_reset(void)
-{
- drag_claimed = false;
-}
-
-
-/**
- *
- */
-
-void ro_gui_selection_drag_claim(wimp_message *message)
-{
- wimp_full_message_drag_claim *claim = (wimp_full_message_drag_claim*)message;
-
- dragging_claimant = message->sender;
- dragging_claimed = true;
-
- /* have we been asked to remove the drag box/sprite? */
- if (claim->flags & wimp_DRAG_CLAIM_SUPPRESS_DRAGBOX) {
- ro_gui_drag_box_cancel();
- }
- else {
- /* \todo - restore it here? */
- }
-
- /* do we need to restore the default pointer shape? */
- if ((last_claim_flags & wimp_DRAG_CLAIM_POINTER_CHANGED) &&
- !(claim->flags & wimp_DRAG_CLAIM_POINTER_CHANGED)) {
- gui_window_set_pointer(last_start_window, GUI_POINTER_DEFAULT);
- }
-
- last_claim_flags = claim->flags;
-}
-
-
-void ro_gui_selection_send_dragging(wimp_pointer *pointer)
-{
- wimp_full_message_dragging dragmsg;
-
- LOG("sending DRAGGING to %p, %d", pointer->w, pointer->i);
-
- dragmsg.size = offsetof(wimp_full_message_dragging, file_types) + 8;
- dragmsg.your_ref = 0;
- dragmsg.action = message_DRAGGING;
- dragmsg.w = pointer->w;
- dragmsg.i = pointer->i;
- dragmsg.pos = pointer->pos;
-/* \todo - this is interesting because it depends upon not just the state of the
- shift key, but also whether it /can/ be deleted, ie. from text area/input
- rather than page contents */
- dragmsg.flags = wimp_DRAGGING_FROM_SELECTION;
- dragmsg.box = dragging_box;
- dragmsg.file_types[0] = osfile_TYPE_TEXT;
- dragmsg.file_types[1] = ~0;
-
- /* if the message_dragmsg messages have been claimed we must address them
- to the claimant task, which is not necessarily the task that owns whatever
- window happens to be under the pointer */
-
- if (dragging_claimed) {
- ro_message_send_message(wimp_USER_MESSAGE_RECORDED,
- (wimp_message*)&dragmsg, dragging_claimant, ro_gui_dragging_bounced);
- }
- else {
- ro_message_send_message_to_window(wimp_USER_MESSAGE_RECORDED,
- (wimp_message*)&dragmsg, pointer->w, pointer->i,
- ro_gui_dragging_bounced, &dragging_claimant);
- }
-}
-
-
-/**
- * Our message_DRAGGING message was bounced, ie. the intended recipient does not
- * support the drag-and-drop protocol or cannot receive the data at the pointer
- * position.
- */
-
-void ro_gui_dragging_bounced(wimp_message *message)
-{
- dragging_claimed = false;
-}
-
-static struct gui_clipboard_table clipboard_table = {
- .get = gui_get_clipboard,
- .set = gui_set_clipboard,
-};
-
-struct gui_clipboard_table *riscos_clipboard_table = &clipboard_table;