/* Copyright 1996 Acorn Computers Ltd * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /************************************************************************/ /* © Acorn Computers Ltd, 1992. */ /* */ /* This file forms part of an unsupported source release of RISC_OSLib. */ /* */ /* It may be freely used to create executable images for saleable */ /* products but cannot be sold in source form or as an object library */ /* without the prior written consent of Acorn Computers Ltd. */ /* */ /* If this file is re-distributed (even if modified) it should retain */ /* this copyright notice. */ /* */ /************************************************************************/ /* Title: c.event * Purpose: central processing for window system events. * History: IDJ: 06-Feb-92: prepared for source release * */ #define BOOL int #define TRUE 1 #define FALSE 0 #include #include "trace.h" #include "os.h" #include "wimp.h" #include "wimpt.h" #include "win.h" #include "menu.h" #include "alarm.h" #include "event.h" /* --------- masking of events ---------- */ static wimp_emask event__mask = wimp_EMNULL; void event_setmask (wimp_emask mask) { event__mask = mask; } wimp_emask event_getmask (void) { return (event__mask); } /* -------- attaching menus. -------- */ /* An event_w is in fact a wimp_w. */ typedef struct { menu m; event_menu_maker maker; event_menu_proc event; void *handle; } mstr; static BOOL event__attach(event_w w, menu m, event_menu_maker menumaker, event_menu_proc eventproc, void *handle) { mstr *p = win_getmenuh(w); if (m == 0 && menumaker == 0) { /* cancelling */ if (p != 0) { /* something to cancel */ free(p); win_setmenuh(w, 0); } } else { if (p == 0) p = malloc(sizeof(mstr)); if (p == 0) return FALSE; p->m = m; p->maker = menumaker; p->event = eventproc; p->handle = handle; win_setmenuh(w, p); } return TRUE; } BOOL event_attachmenu(event_w w, menu m, event_menu_proc eventproc, void* handle) { return event__attach(w, m, 0, eventproc, handle); } BOOL event_attachmenumaker(event_w w, event_menu_maker menumaker, event_menu_proc eventproc, void *handle) { return event__attach(w, 0, menumaker, eventproc, handle); } /* -------- Processing Events. -------- */ static wimp_w event__current_menu_window = 0; /* 0 if no menu currently visible */ static menu event__current_menu = NULL; static BOOL event__current_destroy_after; /* set if we made the menu */ static int event__menux = 0; static int event__menuy = 0; static BOOL event__last_was_menu_hit = FALSE; static BOOL event__recreation; static BOOL event__process(wimp_eventstr *e) { /* Look for submenu requests, and if found turn them into menu hits. */ /* People wishing to respond can pick up the original from wimpt. */ if (e->e == wimp_ESEND && e->data.msg.hdr.action == wimp_MMENUWARN) { int i; e->e = wimp_EMENU; i = 0; while ((e->data.menu[i] = e->data.msg.data.words[i+3]) != -1) i++; e->data.menu[i++] = 0; e->data.menu[i++] = -1; } /* Look for menu events */ if (e->e == wimp_EBUT && (wimp_BMID & e->data.but.m.bbits) != 0) { /* set up a menu! */ mstr *p; if (e->data.but.m.w <= -1) e->data.but.m.w = win_ICONBAR; p = win_getmenuh(e->data.but.m.w); if (p != 0) { wimp_menuhdr *m; event__current_menu_window = e->data.but.m.w; event__current_menu = p->m; event__current_destroy_after = FALSE; if (p->m != 0) { m = (wimp_menuhdr*) menu_syshandle(p->m); } else if (p->maker != 0) { event__current_destroy_after = FALSE; event__recreation = 0 ; event__current_menu = p->maker(p->handle); m = (wimp_menuhdr*) menu_syshandle(event__current_menu); } else { m = (wimp_menuhdr *) -1; } if (event__current_menu_window == win_ICONBAR) { /* move icon bar menus up a bit. */ e->data.but.m.x -= 16 /* m->width/2 */; e->data.but.m.y = 96; { wimp_menuitem *mi = (wimp_menuitem*) (m + 1); while (1) { e->data.but.m.y += m->height + m->gap; if ((mi->flags & wimp_MLAST) != 0) break; mi++; } } } event__menux = e->data.but.m.x; event__menuy = e->data.but.m.y; wimpt_complain(wimp_create_menu((wimp_menustr*) m, e->data.but.m.x - 64, e->data.but.m.y)); return FALSE; } } else if (e->e == wimp_EMENU && event__current_menu != NULL) { mstr *p; p = win_getmenuh(event__current_menu_window); if (p == 0) { /* if the menu registration has been cancelled, we hand the event on. */ } else { int i; char a[20]; for (i = 0; e->data.menu[i] != -1; i++) {a[i] = 1 + e->data.menu[i];} a[i] = 0; p->event(p->handle, a); event__last_was_menu_hit = TRUE; /* menu has still to be deleted. */ return FALSE; } } if (e->e == wimp_ENULL) { int dummy_time; BOOL pending_alarm = alarm_next(&dummy_time); tracef0("Got a null\n"); if (pending_alarm != 0 && dummy_time <= alarm_timenow()) { tracef1("Calling alarm at %d\n", alarm_timenow()); alarm_callnext(); } if ((event_getmask() & wimp_EMNULL) != 0) return TRUE; } /* now process the event */ if (win_processevent(e)) { /* all is well, it was claimed */ } else if (e->e == wimp_ENULL) { /* machine idle: say so */ return TRUE; } else if (e->e == wimp_EOPEN) { /* Assume it's a menu being moved */ wimpt_complain(wimp_open_wind(&e->data.o)); } return FALSE; } static void event__poll(wimp_emask mask, wimp_eventstr *result) { if (event__last_was_menu_hit && wimpt_last_event()->e == wimp_EMENU) { wimp_mousestr m; event__last_was_menu_hit = FALSE; wimpt_noerr(wimp_get_point_info(&m)); if (0 != (wimp_BRIGHT & m.bbits)) { /* An ADJ-hit. The menu should be recreated. */ mstr *p = win_getmenuh(event__current_menu_window); if (p != 0) { wimp_menustr *m; event__current_menu = p->m; event__current_destroy_after = FALSE; if (p->m != 0) { m = (wimp_menustr*) menu_syshandle(p->m); } else if (p->maker != 0) { event__recreation = 1 ; event__current_menu = p->maker(p->handle); m = (wimp_menustr*) menu_syshandle(event__current_menu); } else { m = (wimp_menustr *) -1; } wimpt_complain(wimp_create_menu(m, event__menux, event__menuy)); } } } tracef0("doing poll.\n"); wimpt_complain(wimpt_poll(mask, result)); tracef0("poll done.\n"); } void event_process(void) { tracef0("event_process.\n"); if (win_activeno() == 0) exit(0); /* stop program */ { wimp_eventstr e; event__poll(event_getmask(), &e); (void) event__process(&e); } } #ifndef UROM BOOL event_anywindows() { return(win_activeno() != 0); } #endif void event_clear_current_menu(void) { event__current_menu = NULL; event__current_menu_window = 0; wimpt_noerr(wimp_create_menu((wimp_menustr*) -1, 0, 0)); } BOOL event_is_menu_being_recreated(void) { return event__recreation; } /* end */