182 lines
4.8 KiB
C
182 lines
4.8 KiB
C
/*
|
|
* Copyright 2003 Phil Mellor <monkeyson@users.sourceforge.net>
|
|
* Copyright 2004 James Bursa <bursa@users.sourceforge.net>
|
|
* Copyright 2004 Andrew Timmins <atimmins@blueyonder.co.uk>
|
|
* Copyright 2004 John Tytgat <joty@netsurf-browser.org>
|
|
* 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
|
|
* Textual input handling (implementation)
|
|
*/
|
|
|
|
#include <assert.h>
|
|
#include <ctype.h>
|
|
#include <string.h>
|
|
|
|
#include "desktop/browser.h"
|
|
#include "desktop/gui.h"
|
|
#include "desktop/mouse.h"
|
|
#include "desktop/scrollbar.h"
|
|
#include "desktop/selection.h"
|
|
#include "desktop/textinput.h"
|
|
#include "render/box.h"
|
|
#include "render/font.h"
|
|
#include "render/form.h"
|
|
#include "render/html_internal.h"
|
|
#include "render/layout.h"
|
|
#include "utils/log.h"
|
|
#include "utils/talloc.h"
|
|
#include "utils/utf8.h"
|
|
#include "utils/utils.h"
|
|
|
|
/* Define to enable textinput debug */
|
|
#undef TEXTINPUT_DEBUG
|
|
|
|
|
|
/**
|
|
* Position the caret and assign a callback for key presses.
|
|
*
|
|
* \param bw The browser window in which to place the caret
|
|
* \param x X coordinate of the caret
|
|
* \param y Y coordinate
|
|
* \param height Height of caret
|
|
* \param caret_cb Callback function for keypresses
|
|
* \param paste_cb Callback function for pasting text
|
|
* \param move_cb Callback function for caret movement
|
|
* \param p1 Callback private data pointer, passed to callback function
|
|
* \param p2 Callback private data pointer, passed to callback function
|
|
*/
|
|
void browser_window_place_caret(struct browser_window *bw,
|
|
int x, int y, int height,
|
|
browser_caret_callback caret_cb,
|
|
browser_paste_callback paste_cb,
|
|
browser_move_callback move_cb,
|
|
void *p1, void *p2)
|
|
{
|
|
struct browser_window *root_bw;
|
|
int pos_x = 0;
|
|
int pos_y = 0;
|
|
|
|
/* Find top level browser window */
|
|
root_bw = browser_window_get_root(bw);
|
|
browser_window_get_position(bw, true, &pos_x, &pos_y);
|
|
|
|
x = x * bw->scale + pos_x;
|
|
y = y * bw->scale + pos_y;
|
|
|
|
gui_window_place_caret(root_bw->window, x, y, height * bw->scale);
|
|
bw->caret_callback = caret_cb;
|
|
bw->paste_callback = paste_cb;
|
|
bw->move_callback = move_cb;
|
|
bw->caret_p1 = p1;
|
|
bw->caret_p2 = p2;
|
|
|
|
/* Set focus browser window */
|
|
root_bw->focus = bw;
|
|
}
|
|
|
|
|
|
/**
|
|
* Removes the caret and callback for key process.
|
|
*
|
|
* \param bw The browser window from which to remove caret
|
|
*/
|
|
void browser_window_remove_caret(struct browser_window *bw)
|
|
{
|
|
struct browser_window *root_bw;
|
|
|
|
root_bw = browser_window_get_root(bw);
|
|
|
|
if (root_bw && root_bw->window)
|
|
gui_window_remove_caret(root_bw->window);
|
|
|
|
bw->caret_callback = NULL;
|
|
bw->paste_callback = NULL;
|
|
bw->move_callback = NULL;
|
|
bw->caret_p1 = NULL;
|
|
bw->caret_p2 = NULL;
|
|
}
|
|
|
|
|
|
/**
|
|
* Handle key presses in a browser window.
|
|
*
|
|
* \param bw The root browser window
|
|
* \param key The UCS4 character codepoint
|
|
* \return true if key handled, false otherwise
|
|
*/
|
|
bool browser_window_key_press(struct browser_window *bw, uint32_t key)
|
|
{
|
|
struct browser_window *focus = bw->focus;
|
|
|
|
assert(bw->window != NULL);
|
|
|
|
/* keys that take effect wherever the caret is positioned */
|
|
switch (key) {
|
|
case KEY_SELECT_ALL:
|
|
selection_select_all(bw->cur_sel);
|
|
return true;
|
|
|
|
case KEY_COPY_SELECTION:
|
|
gui_copy_to_clipboard(bw->cur_sel);
|
|
return true;
|
|
|
|
case KEY_CLEAR_SELECTION:
|
|
selection_clear(bw->cur_sel, true);
|
|
return true;
|
|
|
|
case KEY_ESCAPE:
|
|
if (bw->cur_sel && selection_defined(bw->cur_sel)) {
|
|
selection_clear(bw->cur_sel, true);
|
|
return true;
|
|
}
|
|
/* if there's no selection,
|
|
* leave Escape for the caller */
|
|
return false;
|
|
}
|
|
|
|
/* pass on to the appropriate field */
|
|
if (!focus->caret_callback)
|
|
return false;
|
|
|
|
return focus->caret_callback(focus, key,
|
|
focus->caret_p1, focus->caret_p2);
|
|
}
|
|
|
|
|
|
/**
|
|
* Paste a block of text into a browser window at the caret position.
|
|
*
|
|
* \param bw browser window
|
|
* \param utf8 pointer to block of text
|
|
* \param utf8_len length (bytes) of text block
|
|
* \param last true iff this is the last chunk (update screen too)
|
|
* \return true iff successful
|
|
*/
|
|
|
|
bool browser_window_paste_text(struct browser_window *bw, const char *utf8,
|
|
unsigned utf8_len, bool last)
|
|
{
|
|
if (!bw->focus || !bw->focus->paste_callback)
|
|
return false;
|
|
|
|
return bw->focus->paste_callback(bw->focus, utf8, utf8_len, last,
|
|
bw->focus->caret_p1, bw->focus->caret_p2);
|
|
}
|
|
|