NetSurf
global_history.c
Go to the documentation of this file.
1/*
2 * Copyright 2010 Stephen Fryatt <stevef@netsurf-browser.org>
3 * Copyright 2016 Vincent Sanders <vince@netsurf-browser.org>
4 *
5 * This file is part of NetSurf, http://www.netsurf-browser.org/
6 *
7 * NetSurf is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 2 of the License.
10 *
11 * NetSurf is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20/**
21 * \file
22 * Implementation of RISC OS global history.
23 */
24
25#include <stdint.h>
26#include <stdlib.h>
27#include <oslib/wimp.h>
28
29#include "utils/nsoption.h"
30#include "utils/messages.h"
31#include "utils/log.h"
32#include "netsurf/window.h"
33#include "netsurf/plotters.h"
34#include "netsurf/keypress.h"
36
37#include "riscos/dialog.h"
38#include "riscos/gui.h"
39#include "riscos/menus.h"
40#include "riscos/save.h"
41#include "riscos/toolbar.h"
42#include "riscos/wimp.h"
43#include "riscos/wimp_event.h"
44#include "riscos/corewindow.h"
46
49 wimp_menu *menu;
50};
51
52/** global_history window is a singleton */
54
55/** riscos template for global_history window */
57
58
59/**
60 * callback to draw on drawable area of ro global_history window
61 *
62 * \param ro_cw The riscos core window structure.
63 * \param r The rectangle of the window that needs updating.
64 * \param originx The risc os plotter x origin.
65 * \param originy The risc os plotter y origin.
66 * \return NSERROR_OK on success otherwise apropriate error code
67 */
68static nserror
70 int originx,
71 int originy,
72 struct rect *r)
73{
74 struct redraw_context ctx = {
75 .interactive = true,
76 .background_images = true,
77 .plot = &ro_plotters
78 };
79
80 ro_plot_origin_x = originx;
81 ro_plot_origin_y = originy;
82 no_font_blending = true;
83 global_history_redraw(0, 0, r, &ctx);
84 no_font_blending = false;
85
86 return NSERROR_OK;
87}
88
89
90/**
91 * callback for keypress on ro coookie window
92 *
93 * \param ro_cw The ro core window structure.
94 * \param nskey The netsurf key code.
95 * \return NSERROR_OK if key processed,
96 * NSERROR_NOT_IMPLEMENTED if key not processed
97 * otherwise apropriate error code
98 */
99static nserror global_history_key(struct ro_corewindow *ro_cw, uint32_t nskey)
100{
101 if (global_history_keypress(nskey)) {
102 return NSERROR_OK;
103 }
105}
106
107
108/**
109 * callback for mouse event on ro global_history window
110 *
111 * \param ro_cw The ro core window structure.
112 * \param mouse_state mouse state
113 * \param x location of event
114 * \param y location of event
115 * \return NSERROR_OK on sucess otherwise apropriate error code.
116 */
117static nserror
119 browser_mouse_state mouse_state,
120 int x, int y)
121{
122 global_history_mouse_action(mouse_state, x, y);
123
124 return NSERROR_OK;
125}
126
127
128/**
129 * handle clicks in ro core window toolbar.
130 *
131 * \param ro_cw The ro core window structure.
132 * \param action The button bar action.
133 * \return NSERROR_OK if config saved, otherwise apropriate error code
134 */
135static nserror
137 button_bar_action action)
138{
139 switch (action) {
142 break;
143
146 break;
147
150 break;
151
154 break;
155
158 break;
159
162 break;
163
164 default:
165 break;
166 }
167
168 return NSERROR_OK;
169}
170
171
172/**
173 * Handle updating state of buttons in ro core window toolbar.
174 *
175 * \param ro_cw The ro core window structure.
176 * \return NSERROR_OK if config saved, otherwise apropriate error code
177 */
179{
183
187 return NSERROR_OK;
188}
189
190
191/**
192 * callback for saving of toolbar state in ro global history window
193 *
194 * \param ro_cw The ro core window structure.
195 * \param config The new toolbar configuration.
196 * \return NSERROR_OK if config saved, otherwise apropriate error code
197 */
198static nserror
199global_history_toolbar_save(struct ro_corewindow *ro_cw, char *config)
200{
201 nsoption_set_charp(toolbar_history, config);
203
204 return NSERROR_OK;
205}
206
207
208/**
209 * Prepare the global_history menu for display
210 *
211 * \param w The window owning the menu.
212 * \param i The icon owning the menu.
213 * \param menu The menu from which the selection was made.
214 * \param pointer The pointer shape
215 * \return true if action accepted; else false.
216 */
217static bool
219 wimp_i i,
220 wimp_menu *menu,
221 wimp_pointer *pointer)
222{
223 bool selection;
224 struct ro_global_history_window *global_historyw;
225
226 global_historyw = (struct ro_global_history_window *)ro_gui_wimp_event_get_user_data(w);
227
228 if ((global_historyw == NULL) ||
229 (menu != global_historyw->menu)) {
230 return false;
231 }
232
234
237
239 NULL, NULL, NULL, NULL);
240
242 ro_toolbar_menu_option_shade(global_historyw->core.toolbar));
244 ro_toolbar_menu_buttons_tick(global_historyw->core.toolbar));
245
247 ro_toolbar_menu_edit_shade(global_historyw->core.toolbar));
249 ro_toolbar_menu_edit_tick(global_historyw->core.toolbar));
250
251 return true;
252}
253
254
255/**
256 * Handle submenu warnings for the global_history menu
257 *
258 * \param w The window owning the menu.
259 * \param i The icon owning the menu.
260 * \param menu The menu to which the warning applies.
261 * \param selection The wimp menu selection data.
262 * \param action The selected menu action.
263 */
264static void
266 wimp_i i,
267 wimp_menu *menu,
268 wimp_selection *selection,
269 menu_action action)
270{
271 /* Do nothing */
272}
273
274
275/**
276 * Handle selections from the global_history menu
277 *
278 * \param w The window owning the menu.
279 * \param i The icon owning the menu.
280 * \param menu The menu from which the selection was made.
281 * \param selection The wimp menu selection data.
282 * \param action The selected menu action.
283 * \return true if action accepted; else false.
284 */
285static bool
287 wimp_i i,
288 wimp_menu *menu,
289 wimp_selection *selection,
290 menu_action action)
291{
292 struct ro_global_history_window *global_historyw;
293
294 global_historyw = (struct ro_global_history_window *)ro_gui_wimp_event_get_user_data(w);
295
296 if ((global_historyw == NULL) ||
297 (menu != global_historyw->menu)) {
298 return false;
299 }
300
301 switch (action) {
302 case HISTORY_EXPORT:
304 return true;
305
306 case TREE_EXPAND_ALL:
308 return true;
309
312 return true;
313
316 return true;
317
320 return true;
321
324 return true;
325
328 return true;
329
332 return true;
333
336 return true;
337
338 case TREE_SELECT_ALL:
340 return true;
341
344 return true;
345
346 case TOOLBAR_BUTTONS:
348 !ro_toolbar_get_display_buttons(global_historyw->core.toolbar));
349 return true;
350
351 case TOOLBAR_EDIT:
352 ro_toolbar_toggle_edit(global_historyw->core.toolbar);
353 return true;
354
355 default:
356 return false;
357 }
358
359 return false;
360}
361
362
363/**
364 * Creates the window for the global_history tree.
365 *
366 * \return NSERROR_OK on success else appropriate error code on faliure.
367 */
369{
370 os_error *error;
371 struct ro_global_history_window *ncwin;
372 nserror res;
373 static const struct ns_menu global_history_menu_def = {
374 "History", {
375 { "History", NO_ACTION, 0 },
376 { "_History.Export", HISTORY_EXPORT, &dialog_saveas },
377 { "History.Expand", TREE_EXPAND_ALL, 0 },
378 { "History.Expand.All", TREE_EXPAND_ALL, 0 },
379 { "History.Expand.Folders", TREE_EXPAND_FOLDERS, 0 },
380 { "History.Expand.Links", TREE_EXPAND_LINKS, 0 },
381 { "History.Collapse", TREE_COLLAPSE_ALL, 0 },
382 { "History.Collapse.All", TREE_COLLAPSE_ALL, 0 },
383 { "History.Collapse.Folders", TREE_COLLAPSE_FOLDERS, 0 },
384 { "History.Collapse.Links", TREE_COLLAPSE_LINKS, 0 },
385 { "History.Toolbars", NO_ACTION, 0 },
386 { "_History.Toolbars.ToolButtons", TOOLBAR_BUTTONS, 0 },
387 { "History.Toolbars.EditToolbar",TOOLBAR_EDIT, 0 },
388 { "Selection", TREE_SELECTION, 0 },
389 { "Selection.Launch", TREE_SELECTION_LAUNCH, 0 },
390 { "Selection.Delete", TREE_SELECTION_DELETE, 0 },
391 { "SelectAll", TREE_SELECT_ALL, 0 },
392 { "Clear", TREE_CLEAR_SELECTION, 0 },
393 { NULL, 0, 0}
394 }
395 };
396
397 static const struct button_bar_buttons global_history_toolbar_buttons[] = {
398 { "delete", TOOLBAR_BUTTON_DELETE, TOOLBAR_BUTTON_NONE, '0', "0"},
399 { "expand", TOOLBAR_BUTTON_EXPAND, TOOLBAR_BUTTON_COLLAPSE, '1', "1"},
400 { "open", TOOLBAR_BUTTON_OPEN, TOOLBAR_BUTTON_CLOSE, '2', "2"},
401 { "launch", TOOLBAR_BUTTON_LAUNCH, TOOLBAR_BUTTON_NONE, '3', "3"},
402 { NULL, TOOLBAR_BUTTON_NONE, TOOLBAR_BUTTON_NONE, '\0', ""}
403 };
404
405 if (global_history_window != NULL) {
406 return NSERROR_OK;
407 }
408
409 ncwin = calloc(1, sizeof(*ncwin));
410 if (ncwin == NULL) {
411 return NSERROR_NOMEM;
412 }
413
414 /* create window from template */
415 error = xwimp_create_window(dialog_global_history_template,
416 &ncwin->core.wh);
417 if (error) {
418 NSLOG(netsurf, INFO, "xwimp_create_window: 0x%x: %s",
419 error->errnum, error->errmess);
420 ro_warn_user("WimpError", error->errmess);
421 free(ncwin);
422 return NSERROR_NOMEM;
423 }
424
425 ro_gui_set_window_title(ncwin->core.wh, messages_get("GlobalHistory"));
426
427 /* initialise callbacks */
429 ncwin->core.key = global_history_key;
433 /* update is not valid untill global history is initialised */
434 ncwin->core.toolbar_update = NULL;
435
436 /* initialise core window */
437 res = ro_corewindow_init(&ncwin->core,
438 global_history_toolbar_buttons,
439 nsoption_charp(toolbar_history),
441 "HelpGHistoryToolbar");
442 if (res != NSERROR_OK) {
443 free(ncwin);
444 return res;
445 }
446
447 NSLOG(netsurf, INFO, "Created global history corewindow: %p",
448 &ncwin->core);
449
450 res = global_history_init((struct core_window *)ncwin);
451 if (res != NSERROR_OK) {
452 free(ncwin);
453 return res;
454 }
455
456 /* setup toolbar update post global_history manager initialisation */
459
460 /* Build the global_history window menu. */
461 ncwin->menu = ro_gui_menu_define_menu(&global_history_menu_def);
462
464 ncwin->menu, false, false);
471
472 /* memoise window so it can be represented when necessary
473 * instead of recreating every time.
474 */
475 global_history_window = ncwin;
476
477 return NSERROR_OK;
478}
479
480
481/* exported interface documented in riscos/global_history.h */
483{
484 nserror res;
485
487 if (res == NSERROR_OK) {
488 NSLOG(netsurf, INFO, "Presenting");
491 600, 800);
492 } else {
493 NSLOG(netsurf, INFO, "Failed presenting code %d", res);
494 }
495
496 return res;
497}
498
499
500/* exported interface documented in riscos/global_history.h */
502{
504}
505
506
507/* exported interface documented in riscos/global_history.h */
509{
510 nserror res;
511
512 if (global_history_window == NULL) {
513 return NSERROR_OK;
514 }
515
516 res = global_history_fini();
517 if (res == NSERROR_OK) {
519
522 }
523
524 return res;
525}
526
527
528/* exported interface documented in riscos/global_history.h */
530{
531 if ((global_history_window != NULL) &&
532 (global_history_window->core.wh == wh)) {
533 return true;
534 }
535 return false;
536}
537
538
539/* exported interface documented in riscos/global_history.h */
541{
542 if ((global_history_window != NULL) &&
543 (global_history_window->menu == menu)) {
544 return true;
545 }
546 return false;
547}
menu_action
Definition: scaffolding.h:77
@ TREE_EXPAND_FOLDERS
Definition: scaffolding.h:157
@ TREE_EXPAND_ALL
Definition: scaffolding.h:156
@ TREE_COLLAPSE_FOLDERS
Definition: scaffolding.h:160
@ TREE_SELECTION
Definition: scaffolding.h:162
@ TREE_SELECTION_LAUNCH
Definition: scaffolding.h:164
@ TREE_SELECT_ALL
Definition: scaffolding.h:166
@ TREE_CLEAR_SELECTION
Definition: scaffolding.h:167
@ TREE_EXPAND_LINKS
Definition: scaffolding.h:158
@ TOOLBAR_BUTTONS
Definition: scaffolding.h:170
@ TREE_SELECTION_DELETE
Definition: scaffolding.h:165
@ TOOLBAR_EDIT
Definition: scaffolding.h:173
@ HISTORY_EXPORT
Definition: scaffolding.h:128
@ TREE_COLLAPSE_ALL
Definition: scaffolding.h:159
@ TREE_COLLAPSE_LINKS
Definition: scaffolding.h:161
button_bar_action
Definition: button_bar.h:32
@ TOOLBAR_BUTTON_NONE
Definition: button_bar.h:33
@ TOOLBAR_BUTTON_CLOSE
Definition: button_bar.h:57
@ TOOLBAR_BUTTON_LAUNCH
Definition: button_bar.h:58
@ TOOLBAR_BUTTON_DELETE
Definition: button_bar.h:53
@ TOOLBAR_BUTTON_COLLAPSE
Definition: button_bar.h:55
@ TOOLBAR_BUTTON_OPEN
Definition: button_bar.h:56
@ TOOLBAR_BUTTON_EXPAND
Definition: button_bar.h:54
nserror global_history_init(void *core_window_handle)
Initialise the global history.
nserror global_history_expand(bool only_folders)
Expand the treeview's nodes.
nserror global_history_fini(void)
Finalise the global history.
void global_history_redraw(int x, int y, struct rect *clip, const struct redraw_context *ctx)
Redraw the global history.
bool global_history_has_selection(void)
Determine whether there is a selection.
nserror global_history_contract(bool all)
Contract the treeview's nodes.
bool global_history_keypress(uint32_t key)
Key press handling.
void global_history_mouse_action(browser_mouse_state mouse, int x, int y)
Handles all kinds of mouse action.
wimp_w dialog_saveas
Definition: dialog.c:75
void ro_gui_dialog_open_persistent(wimp_w parent, wimp_w w, bool pointer)
Open a persistent dialog box relative to the pointer.
Definition: dialog.c:591
wimp_window * ro_gui_dialog_load_template(const char *template_name)
Load a template without creating a window.
Definition: dialog.c:242
void ro_gui_save_options(void)
Save the current options.
Definition: dialog.c:670
bool ro_gui_dialog_open_top(wimp_w w, struct toolbar *toolbar, int width, int height)
Moves a window to the top of the stack.
Definition: dialog.c:413
nserror
Enumeration of error codes.
Definition: errors.h:29
@ NSERROR_NOT_IMPLEMENTED
Functionality is not implemented.
Definition: errors.h:61
@ NSERROR_NOMEM
Memory exhaustion.
Definition: errors.h:32
@ NSERROR_OK
No error.
Definition: errors.h:30
bool no_font_blending
Definition: font.c:48
static nserror global_history_draw(struct ro_corewindow *ro_cw, int originx, int originy, struct rect *r)
callback to draw on drawable area of ro global_history window
nserror ro_gui_global_history_present(void)
make the global history window visible.
static bool global_history_menu_select(wimp_w w, wimp_i i, wimp_menu *menu, wimp_selection *selection, menu_action action)
Handle selections from the global_history menu.
static wimp_window * dialog_global_history_template
riscos template for global_history window
static bool global_history_menu_prepare(wimp_w w, wimp_i i, wimp_menu *menu, wimp_pointer *pointer)
Prepare the global_history menu for display.
static nserror ro_global_history_init(void)
Creates the window for the global_history tree.
static nserror global_history_toolbar_update(struct ro_corewindow *ro_cw)
Handle updating state of buttons in ro core window toolbar.
static struct ro_global_history_window * global_history_window
global_history window is a singleton
static nserror global_history_mouse(struct ro_corewindow *ro_cw, browser_mouse_state mouse_state, int x, int y)
callback for mouse event on ro global_history window
static nserror global_history_key(struct ro_corewindow *ro_cw, uint32_t nskey)
callback for keypress on ro coookie window
bool ro_gui_global_history_check_menu(wimp_menu *menu)
check if menu handle is for the global history menu
void ro_gui_global_history_initialise(void)
initialise the global history window template ready for subsequent use.
static nserror global_history_toolbar_save(struct ro_corewindow *ro_cw, char *config)
callback for saving of toolbar state in ro global history window
nserror ro_gui_global_history_finalise(void)
Free any resources allocated for the global history window.
static void global_history_menu_warning(wimp_w w, wimp_i i, wimp_menu *menu, wimp_selection *selection, menu_action action)
Handle submenu warnings for the global_history menu.
static nserror global_history_toolbar_click(struct ro_corewindow *ro_cw, button_bar_action action)
handle clicks in ro core window toolbar.
bool ro_gui_global_history_check_window(wimp_w wh)
check if window handle is for the global history window
RISc OS global history interface.
@ THEME_STYLE_GLOBAL_HISTORY_TOOLBAR
Definition: theme.h:36
#define NO_ACTION
Definition: idna.c:695
browser_mouse_state
Mouse state: 1 is primary mouse button.
Definition: mouse.h:52
Target independent plotting interface.
Interface to platform-specific graphical user interface window operations.
@ GUI_SAVE_HISTORY_EXPORT_HTML
Definition: window.h:51
Interface to key press operations.
@ NS_KEY_CR
Definition: keypress.h:40
@ NS_KEY_SELECT_ALL
Definition: keypress.h:32
@ NS_KEY_CLEAR_SELECTION
Definition: keypress.h:45
@ NS_KEY_DELETE_LEFT
Definition: keypress.h:35
#define NSLOG(catname, level, logmsg, args...)
Definition: log.h:116
void ro_gui_menu_set_entry_ticked(wimp_menu *menu, menu_action action, bool ticked)
Sets an action within a menu as having a specific ticked status.
Definition: menus.c:831
void ro_gui_menu_set_entry_shaded(wimp_menu *menu, menu_action action, bool shaded)
Sets an action within a menu as having a specific ticked status.
Definition: menus.c:804
wimp_menu * ro_gui_menu_define_menu(const struct ns_menu *menu)
Creates a wimp_menu and adds it to the list to handle actions for.
Definition: menus.c:510
const char * messages_get(const char *key)
Fast lookup of a message by key from the standard Messages hash.
Definition: messages.c:241
Localised message support (interface).
nserror ro_corewindow_fini(struct ro_corewindow *ro_cw)
finalise elements of ro core window.
Definition: corewindow.c:1078
nserror ro_corewindow_init(struct ro_corewindow *ro_cw, const struct button_bar_buttons *tb_buttons, char *tb_order, theme_style tb_style, const char *tb_help)
initialise elements of riscos core window.
Definition: corewindow.c:1003
RISC OS core window interface.
nserror ro_warn_user(const char *warning, const char *detail)
Display a warning for a serious problem (eg memory exhaustion).
Definition: gui.c:2077
int ro_plot_origin_x
Definition: plotters.c:40
int ro_plot_origin_y
Definition: plotters.c:41
const struct plotter_table ro_plotters
RISC OS plotter operation table.
Definition: plotters.c:727
File/object/selection saving (Interface).
void ro_toolbar_set_display_buttons(struct toolbar *toolbar, bool display)
Set the display button bar state for a toolbar.
Definition: toolbar.c:1703
bool ro_toolbar_toggle_edit(struct toolbar *toolbar)
Toggle toolbar edit mode on the given toolbar.
Definition: toolbar.c:1780
void ro_toolbar_set_button_shaded_state(struct toolbar *toolbar, button_bar_action action, bool shaded)
Set the shaded state of a toolbar button.
Definition: toolbar.c:1586
bool ro_toolbar_get_display_buttons(struct toolbar *toolbar)
Return true or false depending on whether the given toolbar is set to display the button bar.
Definition: toolbar.c:1745
Window toolbars (interface).
#define ro_toolbar_menu_edit_tick(toolbar)
Definition: toolbar.h:97
#define ro_toolbar_menu_option_shade(toolbar)
Definition: toolbar.h:82
#define ro_toolbar_menu_buttons_tick(toolbar)
Definition: toolbar.h:85
#define ro_toolbar_menu_edit_shade(toolbar)
Definition: toolbar.h:95
void ro_gui_save_prepare(gui_save_type save_type, struct hlcache_handle *h, char *s, const nsurl *url, const char *title)
Prepares the save box to reflect gui_save_type and a content, and opens it.
Definition: save.c:437
Definition: menus.h:159
Rectangle coordinates.
Definition: types.h:40
Redraw context.
Definition: plotters.h:51
bool interactive
Redraw to show interactive features.
Definition: plotters.h:59
ro core window state
Definition: corewindow.h:39
nserror(* toolbar_click)(struct ro_corewindow *ro_cw, button_bar_action action)
callback for clicks in ro core window toolbar.
Definition: corewindow.h:98
nserror(* mouse)(struct ro_corewindow *ro_cw, browser_mouse_state mouse_state, int x, int y)
callback for mouse event on ro core window
Definition: corewindow.h:89
nserror(* toolbar_save)(struct ro_corewindow *ro_cw, char *config)
callback for saving ro core window toolbar state.
Definition: corewindow.h:115
wimp_w wh
window handle
Definition: corewindow.h:41
nserror(* key)(struct ro_corewindow *ro_cw, uint32_t nskey)
callback for keypress on ro core window
Definition: corewindow.h:78
nserror(* draw)(struct ro_corewindow *ro_cw, int originx, int originy, struct rect *r)
callback to draw on drawable area of ro core window
Definition: corewindow.h:67
nserror(* toolbar_update)(struct ro_corewindow *ro_cw)
callback for updating state of buttons in ro core window toolbar.
Definition: corewindow.h:106
struct toolbar * toolbar
toolbar
Definition: corewindow.h:44
struct ro_corewindow core
Option reading and saving interface.
#define nsoption_charp(OPTION)
Get the value of a string option.
Definition: nsoption.h:331
#define nsoption_set_charp(OPTION, VALUE)
set string option in default table
Definition: nsoption.h:372
void ro_gui_set_window_title(wimp_w w, const char *text)
Set a window title.
Definition: wimp.c:675
General RISC OS WIMP/OS library functions (interface).
void * ro_gui_wimp_event_get_user_data(wimp_w w)
Gets the user data associated with a window.
Definition: wimp_event.c:486
bool ro_gui_wimp_event_register_menu_selection(wimp_w w, bool(*callback)(wimp_w w, wimp_i i, wimp_menu *m, wimp_selection *s, menu_action a))
Register a function to be called following a menu selection.
Definition: wimp_event.c:1581
bool ro_gui_wimp_event_register_menu_prepare(wimp_w w, bool(*callback)(wimp_w w, wimp_i i, wimp_menu *m, wimp_pointer *p))
Register a function to be called before a menu is (re-)opened.
Definition: wimp_event.c:1559
bool ro_gui_wimp_event_register_menu_warning(wimp_w w, void(*callback)(wimp_w w, wimp_i i, wimp_menu *m, wimp_selection *s, menu_action a))
Register a function to be called when a sub-menu warning is received.
Definition: wimp_event.c:1603
bool ro_gui_wimp_event_register_menu(wimp_w w, wimp_menu *m, bool menu_auto, bool position_ibar)
Register a window menu to be (semi-)automatically handled.
Definition: wimp_event.c:1270
Automated RISC OS WIMP event handling (interface).