NetSurf
wimp_event.c
Go to the documentation of this file.
1/*
2 * Copyright 2005 Richard Wilson <info@tinct.net>
3 * Copyright 2010, 2011 Stephen Fryatt <stevef@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/** \file
21 * Automated RISC OS WIMP event handling (implementation).
22 */
23
24#include <assert.h>
25#include <inttypes.h>
26#include <stdbool.h>
27#include <stdlib.h>
28#include <stdio.h>
29#include <string.h>
30#include "oslib/os.h"
31#include "oslib/osbyte.h"
32#include "oslib/serviceinternational.h"
33#include "oslib/wimp.h"
34
35#include "utils/log.h"
36
37#include "riscos/gui.h"
38#include "riscos/dialog.h"
39#include "riscos/menus.h"
40#include "riscos/ucstables.h"
41#include "riscos/wimp.h"
42#include "riscos/wimp_event.h"
43#include "riscos/wimputils.h"
44
45#define WIN_HASH_SIZE 32
46#define WIN_HASH(w) (((unsigned)(w) >> 5) % WIN_HASH_SIZE)
47
48typedef enum {
60
63 int min;
64 int max;
66};
67
69 wimp_i field;
70 wimp_menu *menu;
71};
72
73struct icon_event {
75 wimp_i i;
76 union {
81 void (*callback)(wimp_pointer *pointer);
83 union {
84 char *textual;
85 bool boolean;
89};
90
92 wimp_w w;
93 bool (*ok_click)(wimp_w w);
94 bool (*mouse_click)(wimp_pointer *pointer);
95 bool (*keypress)(wimp_key *key);
96 void (*open_window)(wimp_open *open);
97 void (*close_window)(wimp_w w);
98 void (*redraw_window)(wimp_draw *redraw);
99 void (*scroll_window)(wimp_scroll *scroll);
100 void (*entering_window)(wimp_entering *entering);
101 bool (*menu_prepare)(wimp_w w, wimp_i i, wimp_menu *m,
102 wimp_pointer *p);
103 bool (*menu_selection)(wimp_w w, wimp_i i, wimp_menu *m,
104 wimp_selection *s, menu_action a);
105 void (*menu_warning)(wimp_w w, wimp_i i, wimp_menu *m,
106 wimp_selection *s, menu_action a);
107 void (*menu_close)(wimp_w w, wimp_i i, wimp_menu *m);
108 wimp_menu *window_menu;
111 const char *help_prefix;
112 const char *(*get_help_suffix)(wimp_w w, wimp_i i, os_coord *pos,
113 wimp_mouse_state buttons);
118};
119
120static void ro_gui_wimp_event_ok_click(struct event_window *window,
121 wimp_mouse_state state);
122static struct event_window *ro_gui_wimp_event_get_window(wimp_w w);
123static struct event_window *ro_gui_wimp_event_find_window(wimp_w w);
124static struct icon_event *ro_gui_wimp_event_get_event(wimp_w w, wimp_i i,
126static void ro_gui_wimp_event_prepare_gright_menu(wimp_w w, struct icon_event *event);
127static struct event_window *ro_gui_wimp_event_remove_window(wimp_w w);
128
130
132
133/**
134 * Memorises the current state of any registered components in a window.
135 *
136 * \param w the window to memorise
137 * \return true on success, false on memory exhaustion or for an unknown window
138 */
140{
141 struct event_window *window;
142 struct icon_event *event;
143 bool error = false;
144
146 if (!window)
147 return false;
148
149 for (event = window->first; event; event = event->next) {
150 switch (event->type) {
152 case EVENT_TEXT_FIELD:
153 if (event->previous_value.textual)
154 free(event->previous_value.textual);
155 event->previous_value.textual = strdup(
156 ro_gui_get_icon_string(window->w, event->i));
157 if (!event->previous_value.textual) {
158 error = true;
159 NSLOG(netsurf, INFO,
160 "Unable to store state for icon %i",
161 event->i);
162 }
163 break;
164 case EVENT_CHECKBOX:
165 case EVENT_RADIO:
166 event->previous_value.boolean =
167 ro_gui_get_icon_selected_state(window->w, event->i);
168 break;
169 default:
170 break;
171 }
172 if (event->type != EVENT_MENU_GRIGHT)
173 event->previous_shaded = ro_gui_get_icon_shaded_state(window->w,
174 event->i);
175 }
176 return !error;
177}
178
179
180/**
181 * Restore the state of any registered components in a window to their memorised state.
182 *
183 * \param w the window to restore
184 * \return true on success, false for an unknown window
185 */
187{
188 struct event_window *window;
189 struct icon_event *event;
190
192 if (!window)
193 return false;
194
195 for (event = window->first; event; event = event->next) {
196 switch (event->type) {
198 case EVENT_TEXT_FIELD:
199 if (event->previous_value.textual)
200 ro_gui_set_icon_string(window->w, event->i,
201 event->previous_value.textual, true);
202 break;
203 case EVENT_CHECKBOX:
204 case EVENT_RADIO:
205 ro_gui_set_icon_selected_state(window->w, event->i,
206 event->previous_value.boolean);
207 break;
208 default:
209 break;
210 }
211 if (event->type != EVENT_MENU_GRIGHT)
212 ro_gui_set_icon_shaded_state(window->w, event->i,
213 event->previous_shaded);
214 }
215 return true;
216}
217
218
219/**
220 * Ensures all values are within pre-determined boundaries.
221 *
222 * \param w the window to memorise
223 * \return true on success, false for an unknown window
224 */
226{
227 struct event_window *window;
228 struct icon_event *event;
229 int value;
230
232 if (!window)
233 return false;
234
235 for (event = window->first; event; event = event->next) {
236 switch (event->type) {
238 value = ro_gui_get_icon_decimal(window->w, event->i,
240 if (value < event->data.numeric_field.min)
241 value = event->data.numeric_field.min;
242 else if (value > event->data.numeric_field.max)
243 value = event->data.numeric_field.max;
244 ro_gui_set_icon_decimal(window->w, event->i, value,
246 break;
247 default:
248 break;
249 }
250 }
251 return true;
252}
253
254/**
255 * Transfer event data from one window to another. This can be used as an
256 * alternative to ro_gui_wimp_event_finalise() and re-registering, if
257 * events need to continue across a change of window handle.
258 *
259 * All aspects of the registered events MUST remain the same in the new
260 * window!
261 *
262 * \param from The current window, which is to be deleted.
263 * \param to The window to which the events should transfer.
264 * \return true on success; false for an unknown window.
265 */
266
268{
269 struct event_window *window;
270 int h;
271
272 NSLOG(netsurf, INFO,
273 "Transferring all events from window 0x%x to window 0x%x",
274 (unsigned int)from,
275 (unsigned int)to);
276
278 if (window == NULL || window->w != from)
279 return false;
280
281 h = WIN_HASH(to);
282 window->w = to;
283 window->next = ro_gui_wimp_event_windows[h];
284 ro_gui_wimp_event_windows[h] = window;
285
287
288 return true;
289}
290
291/**
292 * Free any resources associated with a window.
293 *
294 * \param w the window to free resources for
295 */
297{
298 struct event_window *window;
299 struct icon_event *event;
300
301 NSLOG(netsurf, INFO, "Removing all events for window 0x%x",
302 (unsigned int)w);
304 if (!window)
305 return;
306
307 while (window->first) {
308 event = window->first;
309 window->first = event->next;
310 switch (event->type) {
312 case EVENT_TEXT_FIELD:
313 if (event->previous_value.textual)
314 free(event->previous_value.textual);
315 event->previous_value.textual = NULL;
316 break;
317 default:
318 break;
319 }
320 free(event);
321 }
322 free(window);
323 return;
324}
325
326
327/**
328 * Free any resources associated with a specific icon in a window.
329 *
330 * \param w The window containing the icon.
331 * \param i The icon to free resources for.
332 */
333
334void ro_gui_wimp_event_deregister(wimp_w w, wimp_i i)
335{
336 struct event_window *window;
337 struct icon_event *event, *parent, *child;
338
339 NSLOG(netsurf, INFO, "Removing all events for window 0x%x, icon %d",
340 (unsigned int)w, (int)i);
342 if (!window)
343 return;
344
345 /* Remove any events that apply to the given icon. */
346
347 event = window->first;
348 parent = NULL;
349
350 while (event != NULL) {
351 child = event->next;
352
353 if (event->i == i) {
354 NSLOG(netsurf, INFO, "Removing event 0x%x",
355 (unsigned int)event);
356
357 if (parent == NULL)
358 window->first = child;
359 else
360 parent->next = child;
361
362 switch (event->type) {
364 case EVENT_TEXT_FIELD:
365 if (event->previous_value.textual)
366 free(event->previous_value.textual);
367 event->previous_value.textual = NULL;
368 break;
369 default:
370 break;
371 }
372
373 free(event);
374 } else {
375 parent = event;
376 }
377
378 event = child;
379 }
380}
381
382
383/**
384 * Set the associated help prefix for a given window.
385 *
386 * \param w the window to get the prefix for
387 * \param help_prefix the prefix to associate with the window (used directly)
388 * \return true on success, or NULL for memory exhaustion
389 */
390bool ro_gui_wimp_event_set_help_prefix(wimp_w w, const char *help_prefix)
391{
392 struct event_window *window;
393
395 if (!window)
396 return false;
397 window->help_prefix = help_prefix;
398 return true;
399}
400
401
402/**
403 * Get the associated help prefix.
404 *
405 * \param w the window to get the prefix for
406 * \return the associated prefix, or NULL
407 */
409{
410 struct event_window *window;
411
413 if (window)
414 return window->help_prefix;
415 return NULL;
416}
417
418
419/**
420 * Register a handler to decode help suffixes for a given window.
421 *
422 */
423
425 const char *(*get_help_suffix)(wimp_w w, wimp_i i,
426 os_coord *pos, wimp_mouse_state buttons))
427{
428 struct event_window *window;
429
431 if (!window)
432 return false;
434 return true;
435}
436
437
438/**
439 * Get the associated help suffix.
440 *
441 * \param w The window to get the suffix for
442 * \param i The icon
443 * \param pos The os coordinates
444 * \param buttons The button state.
445 * \return The associated prefix, or NULL
446 */
447
448const char *ro_gui_wimp_event_get_help_suffix(wimp_w w, wimp_i i,
449 os_coord *pos, wimp_mouse_state buttons)
450{
451 struct event_window *window;
452
454 if (window == NULL || window->get_help_suffix == NULL)
455 return NULL;
456
457 return window->get_help_suffix(w, i, pos, buttons);
458}
459
460
461/**
462 * Sets the user data associated with a window.
463 *
464 * \param w the window to associate the data with
465 * \param user the data to associate
466 */
467bool ro_gui_wimp_event_set_user_data(wimp_w w, void *user)
468{
469 struct event_window *window;
470
472 if (!window)
473 return false;
474 window->user_data = user;
475 return true;
476
477}
478
479
480/**
481 * Gets the user data associated with a window.
482 *
483 * \param w the window to retrieve the data for
484 * \return the associated data, or NULL
485 */
487{
488 struct event_window *window;
489
491 if (window)
492 return window->user_data;
493 return NULL;
494}
495
496
497/**
498 * Handles a menu selection event.
499 *
500 * (At present, this is tied to being called from menus.c and relies on that
501 * module decoding the menu into an action code. If menus.c loses its
502 * menu handling in the future, such decoding might need to move here.)
503 *
504 * The order of execution is:
505 *
506 * 1. Try to match the menu to a pop-up menu. If successful, handle it as
507 * this.
508 * 2. Try to match the menu to a window menu. If successful, pass control to
509 * the menu's registered _select handler.
510 * 3. Return event as unhandled.
511 *
512 * \param w the window to owning the menu
513 * \param i the icon owning the menu
514 * \param menu the menu that has been selected
515 * \param selection the selection information
516 * \param action the menu action info from menus.c
517 * \return true if the menu is OK for an Adjust re-open;
518 * else false.
519 */
520bool ro_gui_wimp_event_menu_selection(wimp_w w, wimp_i i, wimp_menu *menu,
521 wimp_selection *selection, menu_action action)
522{
523 struct event_window *window;
524 struct icon_event *event;
525 wimp_menu_entry *menu_entry;
526 wimp_key key;
527 os_error *error;
528 wimp_caret caret;
529 wimp_icon_state ic;
530 unsigned int button_type;
531 bool prepared;
532
534 if (window == NULL)
535 return false;
536
537 /* Start by looking for an icon event that matches. If there isn't one,
538 * then return details for an unconnected menu. It's up to the
539 * event recipient to sort out if this is a window menu or not, based
540 * on the menu handle passed back.
541 */
542
543 for (event = window->first; event; event = event->next)
544 if ((event->type == EVENT_MENU_GRIGHT) && (event->i == i))
545 break;
546 if (!event) {
547 if (window->menu_selection)
548 window->menu_selection(window->w, wimp_ICON_WINDOW,
549 menu, selection, action);
550
551 /* Prepare the menu pending a possible Adjust click. */
552 if (window->menu_prepare)
553 if (!window->menu_prepare(window->w, wimp_ICON_WINDOW,
554 menu, NULL))
555 return false;
556
557 return true;
558 }
559
560 menu_entry = &menu->entries[selection->items[0]];
561 for (i = 1; selection->items[i] != -1; i++)
562 menu_entry = &menu_entry->sub_menu->
563 entries[selection->items[i]];
564
565 /* if the entry is already ticked then we do nothing */
566 if (menu_entry->menu_flags & wimp_MENU_TICKED)
567 return true;
568
570 menu_entry->data.indirected_text.text, false);
571 if (window->menu_selection)
572 window->menu_selection(window->w, event->i, menu,
573 selection, action);
574 prepared = true;
575 if (window->menu_prepare)
576 prepared = window->menu_prepare(window->w, event->i,
577 menu, NULL);
578 if (prepared)
580
581 /* set the caret for writable icons and send a CTRL+U keypress to
582 * stimulate activity if needed */
583 ic.w = window->w;
584 ic.i = event->data.menu_gright.field;
585 error = xwimp_get_icon_state(&ic);
586 if (error) {
587 NSLOG(netsurf, INFO, "xwimp_get_icon_state: 0x%x: %s",
588 error->errnum, error->errmess);
589 ro_warn_user("WimpError", error->errmess);
590 return false;
591 }
592 button_type = (ic.icon.flags & wimp_ICON_BUTTON_TYPE) >> wimp_ICON_BUTTON_TYPE_SHIFT;
593 if ((button_type != wimp_BUTTON_WRITABLE) &&
594 (button_type != wimp_BUTTON_WRITE_CLICK_DRAG))
595 return prepared;
596 error = xwimp_get_caret_position(&caret);
597 if (error) {
598 NSLOG(netsurf, INFO, "xwimp_get_caret_position: 0x%x: %s",
599 error->errnum, error->errmess);
600 ro_warn_user("WimpError", error->errmess);
601 return false;
602 }
603 if ((caret.w != window->w) || (caret.i != event->data.menu_gright.field)) {
604 error = xwimp_set_caret_position(window->w, event->data.menu_gright.field,
605 -1, -1, -1, strlen(menu_entry->data.indirected_text.text));
606 if (error) {
607 NSLOG(netsurf, INFO,
608 "xwimp_set_caret_position: 0x%x: %s",
609 error->errnum,
610 error->errmess);
611 ro_warn_user("WimpError", error->errmess);
612 }
613 }
614 if (window->keypress) {
615 key.w = window->w;
616 key.c = 21; // ctrl+u
617 window->keypress(&key);
618 }
619 return prepared;
620}
621
622
623/**
624 * Handles a mouse click event in a registered window.
625 *
626 * The order of execution is:
627 *
628 * 1. If a menu click, and the window has an automatic window menu, this is
629 * processed immediately.
630 * 2. Any registered mouse_click routine (see ro_gui_wimp_register_mouse_click())
631 * 3. If the current icon is not registered with a type then it is assumed that no
632 * action is necessary, and the click is deemed to have been handled.
633 * 4. If the registered mouse_click routine returned false, or there was no registered
634 * routine then the automated action for the registered icon type is performed
635 *
636 * \param pointer the current pointer state
637 * \return true if the event was handled, false otherwise
638 */
639bool ro_gui_wimp_event_mouse_click(wimp_pointer *pointer)
640{
641 struct event_window *window;
642 struct icon_event *event;
643 wimp_w w;
644 struct icon_event *search;
645 int current, step, stepping, min, max, decimal_places;
646 wimp_window_state open;
647 wimp_caret caret;
648 bool prepared;
649
650 w = pointer->w;
652 if (!window)
653 return false;
654
655 /* Menu clicks take priority if there is an auto menu defined. */
656 if ((pointer->buttons == wimp_CLICK_MENU) &&
657 (window->window_menu != NULL) &&
658 (window->window_menu_auto)) {
660 return true;
661 }
662
663 /* registered routines take next priority */
664 if ((window->mouse_click) && (window->mouse_click(pointer)))
665 return true;
666
667 for (event = window->first; event; event = event->next)
668 if (event->i == pointer->i)
669 break;
670 if (!event)
671 return true;
672
673 switch (event->type) {
675 case EVENT_TEXT_FIELD:
676 break;
677 case EVENT_UP_ARROW:
678 case EVENT_DOWN_ARROW:
679 for (search = window->first; search; search = search->next)
680 if (search->i == event->data.linked_icon) break;
681 if (!search) {
682 NSLOG(netsurf, INFO, "Incorrect reference.");
683 return false;
684 }
685 stepping = search->data.numeric_field.stepping;
686 min = search->data.numeric_field.min;
687 max = search->data.numeric_field.max;
688 decimal_places = search->data.numeric_field.decimal_places;
689
690 if (pointer->buttons & wimp_CLICK_ADJUST)
691 step = -stepping;
692 else if (pointer->buttons & wimp_CLICK_SELECT)
693 step = stepping;
694 else
695 return true;
696 if (event->type == EVENT_DOWN_ARROW)
697 step = -step;
698
699 current = ro_gui_get_icon_decimal(pointer->w, event->data.linked_icon,
700 decimal_places);
701 current += step;
702 if (current < min)
703 current = min;
704 if (current > max)
705 current = max;
706 ro_gui_set_icon_decimal(pointer->w, event->data.linked_icon, current,
707 decimal_places);
708 break;
710 /* if there's already a menu open then we assume that we are part of it.
711 * to follow the standard RISC OS behaviour we add a 'send to the back'
712 * button, then close the menu (which closes us) and then finally
713 * re-open ourselves. ugh! */
714 if (current_menu != NULL) {
715 os_error *error;
716 open.w = pointer->w;
717 error = xwimp_get_window_state(&open);
718 if (error) {
719 NSLOG(netsurf, INFO,
720 "xwimp_get_window_state: 0x%x: %s",
721 error->errnum,
722 error->errmess);
723 ro_warn_user("WimpError", error->errmess);
724 return false;
725 }
726 error = xwimp_get_caret_position(&caret);
727 if (error) {
728 NSLOG(netsurf, INFO,
729 "xwimp_get_caret_position: 0x%x: %s",
730 error->errnum,
731 error->errmess);
732 ro_warn_user("WimpError", error->errmess);
733 return false;
734 }
736 pointer->w);
738 error = xwimp_open_window(PTR_WIMP_OPEN(&open));
739 if (error) {
740 NSLOG(netsurf, INFO,
741 "xwimp_open_window: 0x%x: %s",
742 error->errnum,
743 error->errmess);
744 ro_warn_user("WimpError", error->errmess);
745 return false;
746 }
747 if (caret.w == pointer->w) {
748 error = xwimp_set_caret_position(caret.w,
749 caret.i,
750 caret.pos.x, caret.pos.y,
751 -1, caret.index);
752 if (error) {
753 NSLOG(netsurf, INFO,
754 "xwimp_set_caret_position: 0x%x: %s",
755 error->errnum,
756 error->errmess);
757 ro_warn_user("WimpError", error->errmess);
758 }
759 }
760 }
761 /* display the menu */
762
763 prepared = true;
764 if (window->menu_prepare != NULL)
765 prepared = window->menu_prepare(pointer->w, pointer->i,
766 event->data.menu_gright.menu, pointer);
767 if (prepared) {
768 ro_gui_wimp_event_prepare_gright_menu(pointer->w, event);
769 ro_gui_popup_menu(event->data.menu_gright.menu, pointer->w, pointer->i);
770 }
771 break;
772 case EVENT_CHECKBOX:
773 break;
774 case EVENT_RADIO:
775 for (search = window->first; search; search = search->next)
776 if ((search->type == EVENT_RADIO) &&
777 (search->data.radio_group ==
778 event->data.radio_group))
780 search->i, (search == event));
781 break;
782 case EVENT_BUTTON:
783 if (event->data.callback)
784 event->data.callback(pointer);
785 break;
786 case EVENT_CANCEL:
787 if (pointer->buttons & wimp_CLICK_SELECT) {
788 ro_gui_dialog_close(pointer->w);
791 } else {
792 ro_gui_wimp_event_restore(pointer->w);
793 }
794 break;
795 case EVENT_OK:
796 ro_gui_wimp_event_ok_click(window, pointer->buttons);
797 break;
798 }
799 return true;
800}
801
802
803/**
804 * Prepare a menu ready for use
805 *
806 * /param w the window owning the menu
807 * /param event the icon event owning the menu
808 */
810{
811 int i;
812 const char *text;
813 unsigned int button_type;
814 wimp_icon_state ic;
815 wimp_menu *menu;
816 os_error *error;
817
818 /* if the linked icon is not writable then we set the ticked state
819 * of the menu item that matches the contents */
820 ic.w = w;
821 ic.i = event->data.menu_gright.field;
822 error = xwimp_get_icon_state(&ic);
823 if (error) {
824 NSLOG(netsurf, INFO, "xwimp_get_icon_state: 0x%x: %s",
825 error->errnum, error->errmess);
826 ro_warn_user("WimpError", error->errmess);
827 return;
828 }
829 button_type = (ic.icon.flags & wimp_ICON_BUTTON_TYPE)
830 >> wimp_ICON_BUTTON_TYPE_SHIFT;
831 if ((button_type == wimp_BUTTON_WRITABLE) ||
832 (button_type == wimp_BUTTON_WRITE_CLICK_DRAG))
833 return;
835 menu = event->data.menu_gright.menu;
836 i = 0;
837 do {
838 if (!strcmp(menu->entries[i].data.indirected_text.text, text))
839 menu->entries[i].menu_flags |= wimp_MENU_TICKED;
840 else
841 menu->entries[i].menu_flags &= ~wimp_MENU_TICKED;
842 } while (!(menu->entries[i++].menu_flags & wimp_MENU_LAST));
843}
844
845
846/**
847 * Perform the necessary actions following a click on the OK button.
848 *
849 * /param window the window to perform the action on
850 * /param state the mouse button state
851 */
853 wimp_mouse_state state)
854{
855 struct icon_event *search;
856
857 for (search = window->first; search; search = search->next)
858 if (search->type == EVENT_OK) {
859 if (ro_gui_get_icon_shaded_state(window->w, search->i))
860 return;
861 break;
862 }
864
865 if (window->ok_click)
866 if (!window->ok_click(window->w))
867 return;
868
869 if (state & wimp_CLICK_SELECT) {
870 ro_gui_dialog_close(window->w);
873 } else {
875 }
876}
877
878
879/**
880 * Handle any registered keypresses, and the standard RISC OS ones
881 *
882 * \param key the key state
883 * \return true if keypress handled, false otherwise
884 */
885bool ro_gui_wimp_event_keypress(wimp_key *key)
886{
887 static const int *ucstable = NULL;
888 static int alphabet = 0;
889 static uint32_t wc = 0; /* buffer for UTF8 alphabet */
890 static int shift = 0;
891 struct event_window *window;
892 struct icon_event *event;
893 wimp_pointer pointer;
894 wimp_key k;
895 uint32_t c = (uint32_t) key->c;
896 int t_alphabet;
897 os_error *error;
898
899 window = ro_gui_wimp_event_find_window(key->w);
900 if (!window)
901 return false;
902
903 /* copy key state so we can corrupt it safely */
904 memcpy(&k, key, sizeof(wimp_key));
905
906 /* In order to make sensible use of the 0x80->0xFF ranges specified
907 * in the RISC OS 8bit alphabets, we must do the following:
908 *
909 * + Read the currently selected alphabet
910 * + Acquire a pointer to the UCS conversion table for this alphabet:
911 * + Try using ServiceInternational 8 to get the table
912 * + If that fails, use our internal table (see ucstables.c)
913 * + If the alphabet is not UTF8 and the conversion table exists:
914 * + Lookup UCS code in the conversion table
915 * + If code is -1 (i.e. undefined):
916 * + Use codepoint 0xFFFD instead
917 * + If the alphabet is UTF8, we must buffer input, thus:
918 * + If the keycode is < 0x80:
919 * + Handle it directly
920 * + If the keycode is a UTF8 sequence start:
921 * + Initialise the buffer appropriately
922 * + Otherwise:
923 * + OR in relevant bits from keycode to buffer
924 * + If we've received an entire UTF8 character:
925 * + Handle UCS code
926 * + Otherwise:
927 * + Simply handle the keycode directly, as there's no easy way
928 * of performing the mapping from keycode -> UCS4 codepoint.
929 */
930 error = xosbyte1(osbyte_ALPHABET_NUMBER, 127, 0, &t_alphabet);
931 if (error) {
932 NSLOG(netsurf, INFO, "failed reading alphabet: 0x%x: %s",
933 error->errnum, error->errmess);
934 /* prevent any corruption of ucstable */
935 t_alphabet = alphabet;
936 }
937
938 if (t_alphabet != alphabet) {
939 void *ostable;
940 osbool unclaimed;
941 /* Alphabet has changed, so read UCS table location */
942 alphabet = t_alphabet;
943
944 error = xserviceinternational_get_ucs_conversion_table(
945 alphabet, &unclaimed, &ostable);
946 if (error != NULL) {
947 NSLOG(netsurf, INFO,
948 "failed reading UCS conversion table: 0x%x: %s",
949 error->errnum,
950 error->errmess);
951 /* Try using our own table instead */
952 ucstable = ucstable_from_alphabet(alphabet);
953 } else if (unclaimed) {
954 /* Service wasn't claimed so use our own ucstable */
955 ucstable = ucstable_from_alphabet(alphabet);
956 } else {
957 /* Use the table provided by the OS */
958 ucstable = ostable;
959 }
960 }
961
962 if (c < 256) {
963 if (alphabet != 111 /* UTF8 */ && ucstable != NULL) {
964 /* defined in this alphabet? */
965 if (ucstable[c] == -1)
966 return true;
967
968 /* read UCS4 value out of table */
969 k.c = ucstable[c];
970 }
971 else if (alphabet == 111 /* UTF8 */) {
972 if ((c & 0x80) == 0x00 || (c & 0xC0) == 0xC0) {
973 /* UTF8 start sequence */
974 if ((c & 0xE0) == 0xC0) {
975 wc = ((c & 0x1F) << 6);
976 shift = 1;
977 return true;
978 }
979 else if ((c & 0xF0) == 0xE0) {
980 wc = ((c & 0x0F) << 12);
981 shift = 2;
982 return true;
983 }
984 else if ((c & 0xF8) == 0xF0) {
985 wc = ((c & 0x07) << 18);
986 shift = 3;
987 return true;
988 }
989 /* These next two have been removed
990 * from RFC3629, but there's no
991 * guarantee that RISC OS won't
992 * generate a UCS4 value outside the
993 * UTF16 plane, so we handle them
994 * anyway. */
995 else if ((c & 0xFC) == 0xF8) {
996 wc = ((c & 0x03) << 24);
997 shift = 4;
998 }
999 else if ((c & 0xFE) == 0xFC) {
1000 wc = ((c & 0x01) << 30);
1001 shift = 5;
1002 }
1003 else if (c >= 0x80) {
1004 /* If this ever happens,
1005 * RISC OS' UTF8 keyboard
1006 * drivers are broken */
1007 NSLOG(netsurf, INFO,
1008 "unexpected UTF8 start"" byte %x (ignoring)",
1009 c);
1010 return true;
1011 }
1012 /* Anything else is ASCII, so just
1013 * handle it directly. */
1014 }
1015 else {
1016 if ((c & 0xC0) != 0x80) {
1017 /* If this ever happens,
1018 * RISC OS' UTF8 keyboard
1019 * drivers are broken */
1020 NSLOG(netsurf, INFO,
1021 "unexpected keycode: ""%x (ignoring)",
1022 c);
1023 return true;
1024 }
1025
1026 /* Continuation of UTF8 character */
1027 wc |= ((c & 0x3F) << (6 * --shift));
1028 if (shift > 0)
1029 /* partial character */
1030 return true;
1031 else
1032 /* got entire character, so
1033 * fetch from buffer and
1034 * handle it */
1035 k.c = wc;
1036 }
1037 }
1038 } else {
1039 k.c |= IS_WIMP_KEY;
1040 }
1041
1042 /* registered routines take priority */
1043 if (window->keypress)
1044 if (window->keypress(&k))
1045 return true;
1046
1047 switch (key->c) {
1048 /* Escape performs the CANCEL action (simulated click) */
1049 case wimp_KEY_ESCAPE:
1050 for (event = window->first; event; event = event->next) {
1051 switch (event->type) {
1052 case EVENT_CANCEL:
1053 pointer.w = key->w;
1054 pointer.i = event->i;
1055 pointer.buttons = wimp_CLICK_SELECT;
1057 return true;
1058 default:
1059 break;
1060 }
1061 }
1062 return false;
1063 /* CTRL+F2 closes a window with a close icon */
1064 case wimp_KEY_CONTROL + wimp_KEY_F2:
1066 wimp_WINDOW_CLOSE_ICON))
1067 return false;
1068 ro_gui_dialog_close(key->w);
1071 return true;
1072 /* Return performs the OK action */
1073 case wimp_KEY_RETURN:
1074 if (!window->ok_click)
1075 return false;
1076 /* todo: check we aren't greyed out */
1077 ro_gui_wimp_event_ok_click(window, wimp_CLICK_SELECT);
1078 return true;
1079 }
1080 return false;
1081}
1082
1083
1084/**
1085 * Handle any open window requests
1086 *
1087 * \param open the window open request
1088 */
1090{
1091 struct event_window *window;
1092
1093 window = ro_gui_wimp_event_find_window(open->w);
1094 if ((window) && (window->open_window)) {
1095 window->open_window(open);
1096 return true;
1097 }
1098 return false;
1099}
1100
1101
1102/**
1103 * Service any close window handlers
1104 *
1105 * \param w the window being closed
1106 */
1108{
1109 struct event_window *window;
1110
1111 NSLOG(netsurf, INFO, "Close event received for window 0x%x",
1112 (unsigned int)w);
1116 if ((window) && (window->close_window)) {
1117 window->close_window(w);
1118 return true;
1119 }
1120 return false;
1121}
1122
1123
1124/**
1125 * Handle any redraw window requests
1126 *
1127 * \param redraw the window redraw request
1128 */
1129bool ro_gui_wimp_event_redraw_window(wimp_draw *redraw)
1130{
1131 struct event_window *window;
1132
1133 window = ro_gui_wimp_event_find_window(redraw->w);
1134 if ((window) && (window->redraw_window)) {
1135 window->redraw_window(redraw);
1136 return true;
1137 }
1138 return false;
1139}
1140
1141
1142/**
1143 * Handle any scroll window requests
1144 *
1145 * \param scroll the window scroll request
1146 */
1147bool ro_gui_wimp_event_scroll_window(wimp_scroll *scroll)
1148{
1149 struct event_window *window;
1150
1151 window = ro_gui_wimp_event_find_window(scroll->w);
1152 if ((window) && (window->scroll_window)) {
1153 window->scroll_window(scroll);
1154 return true;
1155 }
1156 return false;
1157}
1158
1159
1160/**
1161 * Handle any pointer entering window requests
1162 *
1163 * \param entering the pointer entering window request
1164 */
1166{
1167 struct event_window *window;
1168
1169 window = ro_gui_wimp_event_find_window(entering->w);
1170 if ((window) && (window->entering_window)) {
1171 window->entering_window(entering);
1172 return true;
1173 }
1174 return false;
1175}
1176
1177
1178/**
1179 * Process a Menu click in a window, by checking for a registered window
1180 * menu and opening it if one is found.
1181 *
1182 * \param pointer The pointer block from the mouse click event.
1183 * \return true if the click was actioned; else false.
1184 */
1185
1187{
1188 struct event_window *window;
1189
1190 window = ro_gui_wimp_event_find_window(pointer->w);
1191 if ((window) && (window->window_menu)
1192 && (pointer->buttons == wimp_CLICK_MENU)) {
1193 int xpos, ypos;
1194
1195 if (window->menu_prepare)
1196 if (!window->menu_prepare(window->w, wimp_ICON_WINDOW,
1197 window->window_menu, pointer))
1198 return false;
1199
1200 if (window->window_menu_iconbar) {
1201 int entry = 0;
1202 int line_height = window->window_menu->height +
1203 window->window_menu->gap;
1204 int gap_height = 24; /* The fixed dotted line height */
1205
1206 xpos = pointer->pos.x;
1207 ypos = 96;
1208 do {
1209 ypos += line_height;
1210 if ((window->window_menu->
1211 entries[entry].menu_flags &
1212 wimp_MENU_SEPARATE) != 0)
1213 ypos += gap_height;
1214 } while ((window->window_menu->
1215 entries[entry++].menu_flags &
1216 wimp_MENU_LAST) == 0);
1217 } else {
1218 xpos = pointer->pos.x;
1219 ypos = pointer->pos.y;
1220 }
1221
1222 ro_gui_menu_create(window->window_menu, xpos, ypos, window->w);
1223 return true;
1224 }
1225 return false;
1226}
1227
1228
1229/**
1230 * Trigger a window's Prepare Menu event.
1231 *
1232 * \param w The window to use.
1233 * \param i The icon to use.
1234 * \param *menu The menu handle to use.
1235 * \return true if the affected menu was prepared OK; else
1236 * false.
1237 */
1238
1239bool ro_gui_wimp_event_prepare_menu(wimp_w w, wimp_i i, wimp_menu *menu)
1240{
1241 struct event_window *window;
1242
1244 if (window == NULL)
1245 return false;
1246
1247 if (window->menu_prepare)
1248 return window->menu_prepare(w, i, menu, NULL);
1249
1250 /* The menu is always OK if there's no event handler. */
1251
1252 return true;
1253}
1254
1255/**
1256 * Register a window menu to be (semi-)automatically handled.
1257 *
1258 * \param w The window to attach the menu to.
1259 * \param m The menu to be attached.
1260 * \param menu_auto true if the menu should be opened autimatically on
1261 * Menu clicks with no task intervention; false to pass
1262 * clicks to the window's Mouse Event handler and leave
1263 * that to pass the menu click back to us for handling
1264 * and menu opening.
1265 * \param position_ibar true if the menu should open in an iconbar
1266 * position; false to open at the pointer.
1267 * \return true if the menu was registed ok; else false.
1268 */
1269
1270bool ro_gui_wimp_event_register_menu(wimp_w w, wimp_menu *m,
1271 bool menu_auto, bool position_ibar)
1272{
1273 struct event_window *window;
1274
1276 if (!window)
1277 return false;
1278 window->window_menu = m;
1279 window->window_menu_auto = menu_auto;
1280 window->window_menu_iconbar = position_ibar;
1281 return true;
1282}
1283
1284/**
1285 * Register a numeric field to be automatically handled
1286 */
1288 wimp_i up, wimp_i down,
1289 int min, int max, int stepping, int decimal_places)
1290{
1291 struct icon_event *event;
1292
1294 if (!event)
1295 return false;
1296 event->data.numeric_field.min = min;
1297 event->data.numeric_field.max = max;
1298 event->data.numeric_field.stepping = stepping;
1299 event->data.numeric_field.decimal_places = decimal_places;
1300
1302 if (!event)
1303 return false;
1304 event->data.linked_icon = i;
1305
1307 if (!event)
1308 return false;
1309 event->data.linked_icon = i;
1310
1311 return true;
1312}
1313
1314
1315/**
1316 * Register a text field to be automatically handled
1317 */
1319 struct icon_event *event;
1320
1322 if (!event)
1323 return false;
1324 return true;
1325}
1326
1327
1328/**
1329 * Register an icon menu to be automatically handled
1330 */
1332 wimp_i gright, wimp_menu *menu)
1333{
1334 struct icon_event *event;
1335
1337 if (!event)
1338 return false;
1339 event->data.menu_gright.field = i;
1340 event->data.menu_gright.menu = menu;
1341
1343}
1344
1345
1346/**
1347 * Register a checkbox to be automatically handled
1348 */
1350{
1351 struct icon_event *event;
1352
1354 if (!event)
1355 return false;
1356 return true;
1357}
1358
1359
1360/**
1361 * Register a group of radio icons to be automatically handled
1362 */
1364{
1365 struct event_window *window;
1366
1368 if (!window)
1369 return false;
1370 window->max_radio_group++;
1371
1372 while (*i != -1) {
1373 struct icon_event *event = ro_gui_wimp_event_get_event(w, *i,
1374 EVENT_RADIO);
1375 if (!event)
1376 return false;
1377 event->data.radio_group = window->max_radio_group;
1378 i++;
1379 }
1380 return true;
1381}
1382
1383
1384/**
1385 * Register a function to be called when a particular button is pressed.
1386 */
1388 void (*callback)(wimp_pointer *pointer))
1389{
1390 struct icon_event *event;
1391
1393 if (!event)
1394 return false;
1395 event->data.callback = callback;
1396 return true;
1397}
1398
1399
1400/**
1401 * Register a function to be called for the Cancel action on a window.
1402 */
1404{
1405 struct icon_event *event;
1406
1408 if (!event)
1409 return false;
1410 return true;
1411}
1412
1413
1414/**
1415 * Register a function to be called for the OK action on a window.
1416 */
1417bool ro_gui_wimp_event_register_ok(wimp_w w, wimp_i i,
1418 bool (*callback)(wimp_w w))
1419{
1420 struct event_window *window;
1421 struct icon_event *event;
1422
1423 window = ro_gui_wimp_event_get_window(w);
1424 if (!window)
1425 return false;
1426 window->ok_click = callback;
1427
1429 if (!event)
1430 return false;
1431 return true;
1432}
1433
1434
1435/**
1436 * Register a function to be called for all mouse-clicks to icons
1437 * in a window that don't have registered actions.
1438 */
1440 bool (*callback)(wimp_pointer *pointer))
1441{
1442 struct event_window *window;
1443
1445 if (!window)
1446 return false;
1447 window->mouse_click = callback;
1448 return true;
1449}
1450
1451
1452/**
1453 * Register a function to be called for all keypresses within a
1454 * particular window.
1455 *
1456 * Important: the character code passed to the callback in key->c
1457 * is UTF-32 (i.e. in the range [0, &10ffff]). WIMP keys (e.g. F1)
1458 * will have bit 31 set.
1459 *
1460 */
1462 bool (*callback)(wimp_key *key))
1463{
1464 struct event_window *window;
1465
1467 if (!window)
1468 return false;
1469 window->keypress = callback;
1470 return true;
1471}
1472
1473
1474/**
1475 * Register a function to be called for all window opening requests.
1476 */
1478 void (*callback)(wimp_open *open))
1479{
1480 struct event_window *window;
1481
1483 if (!window)
1484 return false;
1485 window->open_window = callback;
1486 return true;
1487}
1488
1489/**
1490 * Register a function to be called after the window has been closed.
1491 */
1493 void (*callback)(wimp_w w))
1494{
1495 struct event_window *window;
1496
1498 if (!window)
1499 return false;
1500 window->close_window = callback;
1501 return true;
1502}
1503
1504/**
1505 * Register a function to be called for all window redraw operations.
1506 */
1508 void (*callback)(wimp_draw *redraw))
1509{
1510 struct event_window *window;
1511
1513 if (!window)
1514 return false;
1515 window->redraw_window = callback;
1516 return true;
1517}
1518
1519/**
1520 * Register a function to be called for all window scroll requests.
1521 */
1522
1524 void (*callback)(wimp_scroll *scroll))
1525{
1526 struct event_window *window;
1527
1529 if (!window)
1530 return false;
1531 window->scroll_window = callback;
1532 return true;
1533}
1534
1535/**
1536 * Register a function to be called for all pointer entering window requests.
1537 */
1538
1540 void (*callback)(wimp_entering *entering))
1541{
1542 struct event_window *window;
1543
1545 if (!window)
1546 return false;
1547 window->entering_window = callback;
1548 return true;
1549}
1550
1551/**
1552 * Register a function to be called before a menu is (re-)opened.
1553 *
1554 * \param *w The window for which events should be returned.
1555 * \param *callback A function to be called beofre the menu is
1556 * (re-)opened.
1557 * \return true if the menu was registed ok; else false.
1558 */
1560 bool (*callback)(wimp_w w, wimp_i i, wimp_menu *m,
1561 wimp_pointer *p))
1562{
1563 struct event_window *window;
1564
1566 if (!window)
1567 return false;
1568 window->menu_prepare = callback;
1569 return true;
1570}
1571
1572
1573/**
1574 * Register a function to be called following a menu selection.
1575 *
1576 * \param *w The window for which events should be returned.
1577 * \param *callback A function to be called when a selection is
1578 * made.
1579 * \return true if the menu was registed ok; else false.
1580 */
1582 bool (*callback)(wimp_w w, wimp_i i, wimp_menu *m,
1583 wimp_selection *s, menu_action a))
1584{
1585 struct event_window *window;
1586
1588 if (!window)
1589 return false;
1590 window->menu_selection = callback;
1591 return true;
1592}
1593
1594
1595/**
1596 * Register a function to be called when a sub-menu warning is received.
1597 *
1598 * \param *w The window for which events should be returned.
1599 * \param *callback A function to be called whenever a submenu
1600 * warning is received for the menu.
1601 * \return true if the menu was registed ok; else false.
1602 */
1604 void (*callback)(wimp_w w, wimp_i i, wimp_menu *m,
1605 wimp_selection *s, menu_action a))
1606{
1607 struct event_window *window;
1608
1610 if (!window)
1611 return false;
1612 window->menu_warning = callback;
1613 return true;
1614}
1615
1616
1617/**
1618 * Register a function to be called before a menu is finally closed.
1619 *
1620 * \param *w The window for which events should be returned.
1621 * \param *callback A function to be called when the menu is closed.
1622 * \return true if the menu was registed ok; else false.
1623 */
1625 void (*callback)(wimp_w w, wimp_i i, wimp_menu *m))
1626{
1627 struct event_window *window;
1628
1630 if (!window)
1631 return false;
1632 window->menu_close = callback;
1633 return true;
1634}
1635
1636
1637/**
1638 * Finds the event data associated with a given window handle, or creates a
1639 * new one.
1640 *
1641 * \param w the window to find data for
1642 */
1644{
1645 struct event_window *window;
1646 int h;
1647
1648 assert((int)w != 0);
1650 if (window)
1651 return window;
1652
1653 NSLOG(netsurf, INFO, "Creating structure for window 0x%x",
1654 (unsigned int)w);
1655 window = calloc(1, sizeof(struct event_window));
1656 if (!window)
1657 return NULL;
1658
1659 h = WIN_HASH(w);
1660 window->w = w;
1661 window->next = ro_gui_wimp_event_windows[h];
1662 ro_gui_wimp_event_windows[h] = window;
1663 return window;
1664}
1665
1666
1667/**
1668 * Removes the event data associated with a given handle from the hash tables,
1669 * but does not delete it.
1670 *
1671 * \param w the window to be removed
1672 * \return pointer to the event data or NULL if not found
1673 */
1674
1676{
1677 struct event_window **prev;
1678 int h = WIN_HASH(w);
1679
1680 /* search hash chain for the window */
1681 prev = &ro_gui_wimp_event_windows[h];
1682 while (*prev) {
1683 struct event_window *window = *prev;
1684
1685 if (window->w == w) {
1686 /* remove from chain */
1687 *prev = window->next;
1688 return window;
1689 }
1690 prev = &window->next;
1691 }
1692
1693 /* not found */
1694 return NULL;
1695}
1696
1697/**
1698 * Find the event data associated with a given window handle
1699 *
1700 * \param w the window to find data for
1701 */
1703{
1704 struct event_window *window;
1705 int h = WIN_HASH(w);
1706
1707 /* search hash chain for window */
1708 for (window = ro_gui_wimp_event_windows[h]; window; window = window->next) {
1709 if (window->w == w)
1710 return window;
1711 }
1712 return NULL;
1713}
1714
1717{
1718 struct event_window *window;
1719 struct icon_event *event;
1720
1721 window = ro_gui_wimp_event_get_window(w);
1722 if (!window)
1723 return NULL;
1724
1725 for (event = window->first; event; event = event->next) {
1726 if (event->i == i) {
1727 event->type = type;
1728 return event;
1729 }
1730 }
1731
1732 event = calloc(1, sizeof(struct icon_event));
1733 if (!event)
1734 return NULL;
1735 event->i = i;
1736 event->type = type;
1737 event->next = window->first;
1738 window->first = event;
1739
1740 return event;
1741}
1742
1743/* Handle sumbenu warnings. This is called from ro_gui_menu_warning(), and
1744 * returns to that function to have the submenu opened correctly.
1745 *
1746 * \param w the window to owning the menu
1747 * \param i the icon owning the menu
1748 * \param menu the menu that has been selected
1749 * \param selection the selection information
1750 * \param action the menu action info from menus.c
1751 * \return true if the event was handled, false otherwise
1752 */
1753
1754bool ro_gui_wimp_event_submenu_warning(wimp_w w, wimp_i i, wimp_menu *menu,
1755 wimp_selection *selection, menu_action action)
1756{
1757 struct event_window *window;
1758 struct icon_event *event;
1759
1761
1762 /* Process the event for any window menus. Find the window data, then
1763 * try and match to an icon event. If we can, then there isn't anything
1764 * to do.
1765 */
1766
1768 if (!window)
1769 return false;
1770
1771 for (event = window->first; event; event = event->next)
1772 if ((event->type == EVENT_MENU_GRIGHT) && (event->i == i))
1773 break;
1774 if (event) {
1775 if (window->menu_close != NULL &&
1776 event->type == EVENT_MENU_GRIGHT &&
1777 event->data.menu_gright.menu == menu) {
1778 window->menu_close(w, i, menu);
1779 return true;
1780 }
1781
1782 return false;
1783 }
1784
1785 /* If the warning is for a window menu, then pass the event on to it. */
1786
1787 if ((window->window_menu) && (window->window_menu == menu)) {
1788 if (window->menu_warning) {
1789 window->menu_warning(w, wimp_ICON_WINDOW, menu,
1790 selection, action);
1791 return true;
1792 }
1793 }
1794
1795 return false;
1796}
1797
1798/**
1799 * Handle menus being closed. This is called from the menus modules, in
1800 * every scenario when one of our own menus is open.
1801 *
1802 * \param w the window to owning the menu
1803 * \param i the icon owning the menu
1804 * \param menu the menu that has been selected
1805 */
1806
1807void ro_gui_wimp_event_menus_closed(wimp_w w, wimp_i i, wimp_menu *menu)
1808{
1809 struct event_window *window;
1810 struct icon_event *event;
1811
1813
1814 /* Process the event for any window menus. Find the window data, then
1815 * try and match to an icon event. If we can, then GRight menus are
1816 * sent the event; otherwise, we do nothing.
1817 */
1818
1820 if (!window)
1821 return;
1822
1823 for (event = window->first; event; event = event->next)
1824 if ((event->type == EVENT_MENU_GRIGHT) && (event->i == i))
1825 break;
1826 if (event) {
1827 if (window->menu_close != NULL &&
1828 event->type == EVENT_MENU_GRIGHT &&
1829 event->data.menu_gright.menu == menu)
1830 window->menu_close(w, i, menu);
1831 return;
1832 }
1833
1834 /* If the close is for a window menu, then pass the event on to it. */
1835
1836 if ((window->window_menu) && (window->window_menu == menu) &&
1837 (window->menu_close))
1838 window->menu_close(w, wimp_ICON_WINDOW, menu);
1839}
1840
1841/**
1842 * Register a submenu as being opened
1843 */
1845{
1849}
1850
menu_action
Definition: scaffolding.h:77
static int line_height(const css_unit_ctx *unit_len_ctx, const css_computed_style *style)
Calculate line height from a style.
Definition: layout.c:2677
void ro_gui_dialog_add_persistent(wimp_w parent, wimp_w w)
Definition: dialog.c:608
wimp_w parent
Definition: dialog.c:88
void ro_gui_dialog_close(wimp_w close)
Close a dialog box.
Definition: dialog.c:335
const char * type
Definition: filetype.cpp:44
Netsurf additional integer type formatting macros.
#define NSLOG(catname, level, logmsg, args...)
Definition: log.h:116
void ro_gui_menu_destroy(void)
Forcibly close any menu or transient dialogue box that is currently open.
Definition: menus.c:288
void ro_gui_menu_create(wimp_menu *menu, int x, int y, wimp_w w)
Display a menu.
Definition: menus.c:211
void ro_gui_popup_menu(wimp_menu *menu, wimp_w w, wimp_i i)
Display a pop-up menu next to the specified icon.
Definition: menus.c:251
wimp_menu * current_menu
The current menu being worked with (may not be open)
Definition: menus.c:96
void ro_gui_menu_window_changed(wimp_w from, wimp_w to)
Allow the current menu window to change, if the window is deleted and recreated while a menu is activ...
Definition: menus.c:314
nserror ro_warn_user(const char *warning, const char *detail)
Display a warning for a serious problem (eg memory exhaustion).
Definition: gui.c:2076
wimp_w current_menu_window
Window that owns the current menu.
Definition: menus.c:100
Interface to utility string handling.
const char *(* get_help_suffix)(wimp_w w, wimp_i i, os_coord *pos, wimp_mouse_state buttons)
Definition: wimp_event.c:112
bool(* ok_click)(wimp_w w)
Definition: wimp_event.c:93
bool(* mouse_click)(wimp_pointer *pointer)
Definition: wimp_event.c:94
wimp_menu * window_menu
Definition: wimp_event.c:108
const char * help_prefix
Definition: wimp_event.c:111
struct event_window * next
Definition: wimp_event.c:116
void(* redraw_window)(wimp_draw *redraw)
Definition: wimp_event.c:98
void * user_data
Definition: wimp_event.c:114
struct icon_event * first
Definition: wimp_event.c:115
bool(* menu_prepare)(wimp_w w, wimp_i i, wimp_menu *m, wimp_pointer *p)
Definition: wimp_event.c:101
void(* menu_warning)(wimp_w w, wimp_i i, wimp_menu *m, wimp_selection *s, menu_action a)
Definition: wimp_event.c:105
void(* open_window)(wimp_open *open)
Definition: wimp_event.c:96
void(* close_window)(wimp_w w)
Definition: wimp_event.c:97
int max_radio_group
Definition: wimp_event.c:117
void(* menu_close)(wimp_w w, wimp_i i, wimp_menu *m)
Definition: wimp_event.c:107
bool window_menu_auto
Definition: wimp_event.c:109
wimp_w w
Definition: wimp_event.c:92
bool(* keypress)(wimp_key *key)
Definition: wimp_event.c:95
bool(* menu_selection)(wimp_w w, wimp_i i, wimp_menu *m, wimp_selection *s, menu_action a)
Definition: wimp_event.c:103
void(* scroll_window)(wimp_scroll *scroll)
Definition: wimp_event.c:99
void(* entering_window)(wimp_entering *entering)
Definition: wimp_event.c:100
bool window_menu_iconbar
Definition: wimp_event.c:110
event_type type
Definition: wimp_event.c:74
bool boolean
Definition: wimp_event.c:85
wimp_i i
Definition: wimp_event.c:75
union icon_event::@49 data
bool previous_shaded
Definition: wimp_event.c:87
struct icon_event * next
Definition: wimp_event.c:88
char * textual
Definition: wimp_event.c:84
int radio_group
Definition: wimp_event.c:80
struct event_data_menu_gright menu_gright
Definition: wimp_event.c:78
void(* callback)(wimp_pointer *pointer)
Definition: wimp_event.c:81
union icon_event::@50 previous_value
wimp_i linked_icon
Definition: wimp_event.c:79
struct event_data_numeric_field numeric_field
Definition: wimp_event.c:77
const int * ucstable_from_alphabet(int alphabet)
Retrieve UCS table (above), given alphabet number.
Definition: ucstables.c:328
UCS conversion tables (interface) This is only used if nothing claims Service_International,...
char from[32]
Encoding name to convert from.
Definition: utf8.c:143
char to[32]
Encoding name to convert to.
Definition: utf8.c:144
#define min(x, y)
Definition: utils.h:46
#define max(x, y)
Definition: utils.h:50
void ro_gui_set_icon_string(wimp_w w, wimp_i i, const char *text, bool is_utf8)
Set the contents of a text or sprite icon to a string.
Definition: wimp.c:269
int ro_gui_get_icon_decimal(wimp_w w, wimp_i i, int decimal_places)
Get the contents of an icon as a number.
Definition: wimp.c:423
void ro_gui_set_icon_shaded_state(wimp_w w, wimp_i i, bool state)
Set the shaded state of an icon.
Definition: wimp.c:487
const char * ro_gui_get_icon_string(wimp_w w, wimp_i i)
Read the contents of a text or sprite icon.
Definition: wimp.c:235
void ro_gui_set_icon_selected_state(wimp_w w, wimp_i i, bool state)
Set the selected state of an icon.
Definition: wimp.c:444
bool ro_gui_wimp_check_window_furniture(wimp_w w, wimp_window_flags mask)
Checks whether a piece of window furniture is present for a window.
Definition: wimp.c:1066
bool ro_gui_get_icon_shaded_state(wimp_w w, wimp_i i)
Gets the shaded state of an icon.
Definition: wimp.c:535
void ro_gui_set_icon_decimal(wimp_w w, wimp_i i, int value, int decimal_places)
Set the contents of an icon to a number.
Definition: wimp.c:392
bool ro_gui_get_icon_selected_state(wimp_w w, wimp_i i)
Gets the selected state of an icon.
Definition: wimp.c:463
General RISC OS WIMP/OS library functions (interface).
bool ro_gui_wimp_event_register_text_field(wimp_w w, wimp_i i)
Register a text field to be automatically handled.
Definition: wimp_event.c:1318
static wimp_w ro_gui_wimp_event_submenu
Definition: wimp_event.c:131
bool ro_gui_wimp_event_register_keypress(wimp_w w, bool(*callback)(wimp_key *key))
Register a function to be called for all keypresses within a particular window.
Definition: wimp_event.c:1461
bool ro_gui_wimp_event_register_numeric_field(wimp_w w, wimp_i i, wimp_i up, wimp_i down, int min, int max, int stepping, int decimal_places)
Register a numeric field to be automatically handled.
Definition: wimp_event.c:1287
bool ro_gui_wimp_event_set_help_prefix(wimp_w w, const char *help_prefix)
Set the associated help prefix for a given window.
Definition: wimp_event.c:390
const char * ro_gui_wimp_event_get_help_prefix(wimp_w w)
Get the associated help prefix.
Definition: wimp_event.c:408
bool ro_gui_wimp_event_mouse_click(wimp_pointer *pointer)
Handles a mouse click event in a registered window.
Definition: wimp_event.c:639
bool ro_gui_wimp_event_register_redraw_window(wimp_w w, void(*callback)(wimp_draw *redraw))
Register a function to be called for all window redraw operations.
Definition: wimp_event.c:1507
bool ro_gui_wimp_event_register_menu_gright(wimp_w w, wimp_i i, wimp_i gright, wimp_menu *menu)
Register an icon menu to be automatically handled.
Definition: wimp_event.c:1331
static struct event_window * ro_gui_wimp_event_get_window(wimp_w w)
Finds the event data associated with a given window handle, or creates a new one.
Definition: wimp_event.c:1643
void ro_gui_wimp_event_finalise(wimp_w w)
Free any resources associated with a window.
Definition: wimp_event.c:296
void * ro_gui_wimp_event_get_user_data(wimp_w w)
Gets the user data associated with a window.
Definition: wimp_event.c:486
static void ro_gui_wimp_event_ok_click(struct event_window *window, wimp_mouse_state state)
Perform the necessary actions following a click on the OK button.
Definition: wimp_event.c:852
bool ro_gui_wimp_event_transfer(wimp_w from, wimp_w to)
Transfer event data from one window to another.
Definition: wimp_event.c:267
event_type
Definition: wimp_event.c:48
@ EVENT_MENU_GRIGHT
Definition: wimp_event.c:53
@ EVENT_NUMERIC_FIELD
Definition: wimp_event.c:49
@ EVENT_CHECKBOX
Definition: wimp_event.c:54
@ EVENT_UP_ARROW
Definition: wimp_event.c:51
@ EVENT_CANCEL
Definition: wimp_event.c:57
@ EVENT_DOWN_ARROW
Definition: wimp_event.c:52
@ EVENT_RADIO
Definition: wimp_event.c:55
@ EVENT_OK
Definition: wimp_event.c:58
@ EVENT_BUTTON
Definition: wimp_event.c:56
@ EVENT_TEXT_FIELD
Definition: wimp_event.c:50
bool ro_gui_wimp_event_register_cancel(wimp_w w, wimp_i i)
Register a function to be called for the Cancel action on a window.
Definition: wimp_event.c:1403
bool ro_gui_wimp_event_memorise(wimp_w w)
Memorises the current state of any registered components in a window.
Definition: wimp_event.c:139
#define WIN_HASH(w)
Definition: wimp_event.c:46
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_redraw_window(wimp_draw *redraw)
Handle any redraw window requests.
Definition: wimp_event.c:1129
static struct event_window * ro_gui_wimp_event_remove_window(wimp_w w)
Removes the event data associated with a given handle from the hash tables, but does not delete it.
Definition: wimp_event.c:1675
const char * ro_gui_wimp_event_get_help_suffix(wimp_w w, wimp_i i, os_coord *pos, wimp_mouse_state buttons)
Get the associated help suffix.
Definition: wimp_event.c:448
#define WIN_HASH_SIZE
Definition: wimp_event.c:45
bool ro_gui_wimp_event_scroll_window(wimp_scroll *scroll)
Handle any scroll window requests.
Definition: wimp_event.c:1147
bool ro_gui_wimp_event_prepare_menu(wimp_w w, wimp_i i, wimp_menu *menu)
Trigger a window's Prepare Menu event.
Definition: wimp_event.c:1239
bool ro_gui_wimp_event_open_window(wimp_open *open)
Handle any open window requests.
Definition: wimp_event.c:1089
void ro_gui_wimp_event_deregister(wimp_w w, wimp_i i)
Free any resources associated with a specific icon in a window.
Definition: wimp_event.c:334
void ro_gui_wimp_event_register_submenu(wimp_w w)
Register a submenu as being opened.
Definition: wimp_event.c:1844
bool ro_gui_wimp_event_close_window(wimp_w w)
Service any close window handlers.
Definition: wimp_event.c:1107
bool ro_gui_wimp_event_register_mouse_click(wimp_w w, bool(*callback)(wimp_pointer *pointer))
Register a function to be called for all mouse-clicks to icons in a window that don't have registered...
Definition: wimp_event.c:1439
void ro_gui_wimp_event_menus_closed(wimp_w w, wimp_i i, wimp_menu *menu)
Handle menus being closed.
Definition: wimp_event.c:1807
bool ro_gui_wimp_event_register_checkbox(wimp_w w, wimp_i i)
Register a checkbox to be automatically handled.
Definition: wimp_event.c:1349
bool ro_gui_wimp_event_pointer_entering_window(wimp_entering *entering)
Handle any pointer entering window requests.
Definition: wimp_event.c:1165
bool ro_gui_wimp_event_submenu_warning(wimp_w w, wimp_i i, wimp_menu *menu, wimp_selection *selection, menu_action action)
Definition: wimp_event.c:1754
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_restore(wimp_w w)
Restore the state of any registered components in a window to their memorised state.
Definition: wimp_event.c:186
bool ro_gui_wimp_event_validate(wimp_w w)
Ensures all values are within pre-determined boundaries.
Definition: wimp_event.c:225
bool ro_gui_wimp_event_set_user_data(wimp_w w, void *user)
Sets the user data associated with a window.
Definition: wimp_event.c:467
bool ro_gui_wimp_event_register_menu_close(wimp_w w, void(*callback)(wimp_w w, wimp_i i, wimp_menu *m))
Register a function to be called before a menu is finally closed.
Definition: wimp_event.c:1624
bool ro_gui_wimp_event_register_ok(wimp_w w, wimp_i i, bool(*callback)(wimp_w w))
Register a function to be called for the OK action on a window.
Definition: wimp_event.c:1417
bool ro_gui_wimp_event_register_pointer_entering_window(wimp_w w, void(*callback)(wimp_entering *entering))
Register a function to be called for all pointer entering window requests.
Definition: wimp_event.c:1539
bool ro_gui_wimp_event_register_close_window(wimp_w w, void(*callback)(wimp_w w))
Register a function to be called after the window has been closed.
Definition: wimp_event.c:1492
bool ro_gui_wimp_event_register_radio(wimp_w w, wimp_i *i)
Register a group of radio icons to be automatically handled.
Definition: wimp_event.c:1363
bool ro_gui_wimp_event_register_help_suffix(wimp_w w, const char *(*get_help_suffix)(wimp_w w, wimp_i i, os_coord *pos, wimp_mouse_state buttons))
Register a handler to decode help suffixes for a given window.
Definition: wimp_event.c:424
bool ro_gui_wimp_event_menu_selection(wimp_w w, wimp_i i, wimp_menu *menu, wimp_selection *selection, menu_action action)
Handles a menu selection event.
Definition: wimp_event.c:520
bool ro_gui_wimp_event_register_scroll_window(wimp_w w, void(*callback)(wimp_scroll *scroll))
Register a function to be called for all window scroll requests.
Definition: wimp_event.c:1523
static struct event_window * ro_gui_wimp_event_find_window(wimp_w w)
Find the event data associated with a given window handle.
Definition: wimp_event.c:1702
bool ro_gui_wimp_event_keypress(wimp_key *key)
Handle any registered keypresses, and the standard RISC OS ones.
Definition: wimp_event.c:885
bool ro_gui_wimp_event_register_button(wimp_w w, wimp_i i, void(*callback)(wimp_pointer *pointer))
Register a function to be called when a particular button is pressed.
Definition: wimp_event.c:1387
static struct event_window * ro_gui_wimp_event_windows[WIN_HASH_SIZE]
Definition: wimp_event.c:129
bool ro_gui_wimp_event_register_open_window(wimp_w w, void(*callback)(wimp_open *open))
Register a function to be called for all window opening requests.
Definition: wimp_event.c:1477
static struct icon_event * ro_gui_wimp_event_get_event(wimp_w w, wimp_i i, event_type type)
Definition: wimp_event.c:1715
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
static void ro_gui_wimp_event_prepare_gright_menu(wimp_w w, struct icon_event *event)
Prepare a menu ready for use.
Definition: wimp_event.c:809
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
bool ro_gui_wimp_event_process_window_menu_click(wimp_pointer *pointer)
Process a Menu click in a window, by checking for a registered window menu and opening it if one is f...
Definition: wimp_event.c:1186
Automated RISC OS WIMP event handling (interface).
#define IS_WIMP_KEY
Definition: wimp_event.h:37
A collection of grubby utilities for working with OSLib's wimp API.
#define PTR_WIMP_OPEN(pstate)
Definition: wimputils.h:39
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