Commit 39128431 authored by Neil Turton's avatar Neil Turton
Browse files

Import from cleaned 360 CD

parents
s/** gitlab-language=armasm linguist-language=armasm linguist-detectable=true
c/** gitlab-language=c linguist-language=c linguist-detectable=true
h/** gitlab-language=c linguist-language=c linguist-detectable=true
cmhg/** gitlab-language=cmhg linguist-language=cmhg linguist-detectable=true
*,fe1 gitlab-language=make linguist-language=make linguist-detectable=true
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
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.
# Makefile for Menu
#
# ***********************************
# *** C h a n g e L i s t ***
# ***********************************
# Date Name Description
# ---- ---- -----------
# 06-Jan-94 AMcC Created
#
#
# Component specific options:
#
COMPONENT = Menu
ROM_MODULE = aof.${COMPONENT}
#
# Export Paths for Messages module
#
RESDIR = <resource$dir>.Resources2.${COMPONENT}
#
# Generic options:
#
MKDIR = cdir
CC = cc
CMHG = cmhg
CP = copy
LD = link
RM = remove
WIPE = -wipe
CPFLAGS = ~cfr~v
WFLAGS = ~c~v
CFLAGS = -c -depend !Depend ${INCLUDES} -zM -ffah -zps1 ${DFLAGS}
DFLAGS = -DROM
INCLUDES = -Itbox:,C:
#
# Libraries
#
ANSILIB = CLib:o.ansilib
CLIB = CLIB:o.stubs
RLIB = RISCOSLIB:o.risc_oslib
ROMCSTUBS = RISCOSLIB:o.romcstubs
ABSSYM = RISC_OSLib:o.abssym
TBOXLIB = tbox:tboxlib
OBJS =\
o.Modhdr_NoD\
o.Menu\
o.auxiliary\
o.copy\
o.create\
o.delete\
o.events\
o.getstate\
o.hide\
o.miscop\
o.show\
o.task
#
# Rule patterns
#
.c.o:; ${CC} ${CFLAGS} -o $@ $<
.cmhg.o:; ${CMHG} -O $@ $<
#
# Main rules:
#
#
rom: ${ROM_MODULE}
@echo ${COMPONENT}: Module built (ROM)
install_rom: ${ROM_MODULE}
${CP} ${ROM_MODULE} ${INSTDIR}.${COMPONENT} ${CPFLAGS}
@echo ${COMPONENT}: Module installed (ROM)
resources: Messages
${MKDIR} ${RESDIR}
${CP} Messages ${RESDIR}.Messages ${CPFLAGS}
@echo ${COMPONENT}: resource files copied to Messages module
clean:
${WIPE} o.* ${WFLAGS}
${WIPE} aof ${WFLAGS}
${WIPE} linked ${WFLAGS}
${WIPE} map ${WFLAGS}
@echo ${COMPONENT}: cleaned
${ROM_MODULE}: ${OBJS} ${TBOXLIB} ${ROMCSTUBS}
${MKDIR} aof
${LD} -o $@ -aof ${OBJS} ${TBOXLIB} ${ROMCSTUBS}
# final link for ROM Image (using given base address)
rom_link:
${MKDIR} linked
${MKDIR} map
${LD} -o linked.${COMPONENT} -bin -base ${ADDRESS} ${ROM_MODULE} ${ABSSYM} \
-map > map.${COMPONENT}
truncate map.${COMPONENT} linked.${COMPONENT}
${CP} linked.${COMPONENT} ${LINKDIR}.${COMPONENT} ${CPFLAGS}
@echo ${COMPONENT}: rom_link complete
#---------------------------------------------------------------------------
# Dynamic dependencies:
# Project: Menu
# Toolflags:
CCflags = -c -depend !Depend -IC: -throwback -zM -ffah -zps1
C++flags = -c -depend !Depend -throwback -IC:
Pascalflags = -c -depend !Depend -throwback -IP:
Linkflags = -m -o $@
ObjAsmflags = -depend !Depend -ThrowBack -Stamp -quit -CloseExec
CMHGflags =
LibFileflags = -c -o $@
Squeezeflags = -o $@
AAsmflags = -depend !Depend -quit -CloseExec -To $@ -From
# Final targets:
@.Menu: C:o.stubs @.o.auxiliary @.o.copy @.o.create @.o.delete @.o.events \
@.o.getstate @.o.hide @.o.Menu @.o.miscop @.o.show @.o.task @.o.Modhdr_NoD @.o.messages \
@.^.common.tboxlib
link $(linkflags) C:o.stubs @.o.auxiliary @.o.copy @.o.create \
@.o.delete @.o.events @.o.getstate @.o.hide @.o.Menu @.o.miscop @.o.show @.o.task \
@.o.Modhdr_NoD @.o.messages @.^.common.tboxlib
# User-editable dependencies:
@.MenuM: @.messages
modgen @.MenuM MenuM "Menu Messages" 1.00 @.messages Resources.Menu.Messages
@.o.messages: @.Messages
resgen messages_file @.o.messages @.Messages Resources.Menu.Messages
# Static dependencies:
@.o.auxiliary: @.c.auxiliary
cc $(ccflags) -o @.o.auxiliary @.c.auxiliary
@.o.copy: @.c.copy
cc $(ccflags) -o @.o.copy @.c.copy
@.o.create: @.c.create
cc $(ccflags) -o @.o.create @.c.create
@.o.delete: @.c.delete
cc $(ccflags) -o @.o.delete @.c.delete
@.o.events: @.c.events
cc $(ccflags) -o @.o.events @.c.events
@.o.getstate: @.c.getstate
cc $(ccflags) -o @.o.getstate @.c.getstate
@.o.hide: @.c.hide
cc $(ccflags) -o @.o.hide @.c.hide
@.o.Menu: @.c.Menu
cc $(ccflags) -o @.o.Menu @.c.Menu
@.o.miscop: @.c.miscop
cc $(ccflags) -o @.o.miscop @.c.miscop
@.o.show: @.c.show
cc $(ccflags) -o @.o.show @.c.show
@.o.task: @.c.task
cc $(ccflags) -o @.o.task @.c.task
@.o.Modhdr_NoD: @.cmhg.Modhdr_NoD
cmhg @.cmhg.Modhdr_NoD -o @.o.Modhdr_NoD
# Dynamic dependencies:
# 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.
#
# Makefile for Menu
#
# ***********************************
# *** C h a n g e L i s t ***
# ***********************************
# Date Name Description
# ---- ---- -----------
# 06-Jan-94 AMcC Created
#
#
# Component specific options:
#
COMPONENT = Menu
ROM_MODULE = aof.${COMPONENT}
#
# Export Paths for Messages module
#
RESDIR = <resource$dir>.Resources2.${COMPONENT}
#
# Generic options:
#
MKDIR = cdir
CC = cc
CMHG = cmhg
CP = copy
LD = link
RM = remove
WIPE = -wipe
CPFLAGS = ~cfr~v
WFLAGS = ~c~v
CFLAGS = -c -depend !Depend ${INCLUDES} -zM -ffah -zps1 ${DFLAGS}
DFLAGS = -DROM
INCLUDES = -Itbox:,C:
#
# Libraries
#
ANSILIB = CLib:o.ansilib
CLIB = CLIB:o.stubs
RLIB = RISCOSLIB:o.risc_oslib
ROMCSTUBS = RISCOSLIB:o.romcstubs
ABSSYM = RISC_OSLib:o.abssym
TBOXLIB = tbox:tboxlib
OBJS =\
o.Modhdr_NoD\
o.Menu\
o.auxiliary\
o.copy\
o.create\
o.delete\
o.events\
o.getstate\
o.hide\
o.miscop\
o.show\
o.task
#
# Rule patterns
#
.c.o:; ${CC} ${CFLAGS} -o $@ $<
.cmhg.o:; ${CMHG} -O $@ $<
#
# Main rules:
#
#
rom: ${ROM_MODULE}
@echo ${COMPONENT}: Module built (ROM)
install_rom: ${ROM_MODULE}
${CP} ${ROM_MODULE} ${INSTDIR}.${COMPONENT} ${CPFLAGS}
@echo ${COMPONENT}: Module installed (ROM)
resources: Messages
${MKDIR} ${RESDIR}
${CP} Messages ${RESDIR}.Messages ${CPFLAGS}
@echo ${COMPONENT}: resource files copied to Messages module
clean:
${WIPE} o.* ${WFLAGS}
${WIPE} aof ${WFLAGS}
${WIPE} linked ${WFLAGS}
${WIPE} map ${WFLAGS}
@echo ${COMPONENT}: cleaned
${ROM_MODULE}: ${OBJS} ${TBOXLIB} ${ROMCSTUBS}
${MKDIR} aof
${LD} -o $@ -aof ${OBJS} ${TBOXLIB} ${ROMCSTUBS}
# final link for ROM Image (using given base address)
rom_link:
${MKDIR} linked
${MKDIR} map
${LD} -o linked.${COMPONENT} -bin -base ${ADDRESS} ${ROM_MODULE} ${ABSSYM} \
-map > map.${COMPONENT}
truncate map.${COMPONENT} linked.${COMPONENT}
${CP} linked.${COMPONENT} ${LINKDIR}.${COMPONENT} ${CPFLAGS}
@echo ${COMPONENT}: rom_link complete
#---------------------------------------------------------------------------
# Dynamic dependencies:
E00:Menu has active tasks.
E01:Memory allocation failed.
E02:Buffer too short.
E11:Task, %0, does not exist.
E12:Method, %0, not recognised.
E13:MiscOp method, %0, not recognised.
E14:Component, %1, does not exist.
E21:Component, %1, of object, %0, is a sprite and not text.
E22:Component, %1, of object, %0, is text and not a sprite.
E31:Cannot attach submenu, parent object, %0, is not a menu.
E32:Submenu (component, %1, of object, %0) not known.
E33:No sprite specified.
/* 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.
*/
/* Title: Menu.c
* Purpose: main module of a Menu Object module
* Author: TGR
* History: 2-Nov-93: TGR: created from IDJ template
*
*/
#include <stdio.h>
#include <stdlib.h>
#include "kernel.h"
#include "swis.h"
#include "const.h"
#include "macros.h"
#include "string32.h"
#include "messages.h"
#include "objects.toolbox.h"
#include "objects.menu.h"
#include "services.h"
#include "debug.h"
#include "rmensure.h"
#include "mem.h"
#include "os.h"
#include "auxiliary.h"
#include "create.h"
#include "delete.h"
#include "copy.h"
#include "show.h"
#include "hide.h"
#include "getstate.h"
#include "miscop.h"
#include "events.h"
#include "task.h"
#include "Menu.h"
#define MAX_CLASS_SWI_METHODS 7
static _kernel_oserror *(*class_swi_methods [MAX_CLASS_SWI_METHODS])(_kernel_swi_regs *r, TaskDescriptor *t) =
{
create_menu,
delete_menu,
NULL, /*copy_menu,*/
show_menu,
hide_menu,
getstate_menu,
miscop_menu
};
/* +++++++++++++++++++++++++++++++++ finalisation code +++++++++++++++++++++++++++++++++ */
#ifdef ROM
static _kernel_oserror *__ROM;
#endif
extern _kernel_oserror *Menu_finalise (int fatal, int podule, void *pw)
{
_kernel_swi_regs regs;
#ifndef ROM
extern int messages_file(void);
#endif
IGNORE(fatal);
IGNORE(podule);
IGNORE(pw);
/*
* refuse to finalise if tasks active
*/
if (task_any_active())
return make_error (Menu_TasksActive, 0);
/*
* close our messages file
*/
messages_file_close ();
#ifndef ROM
/*
* ... and deregister from ResourceFS
*/
regs.r[0] = messages_file();
_kernel_swi (ResourceFS_DeregisterFiles, &regs, &regs);
#endif
/* hide menus before deletion */
if (global_menu.flags & GLOBAL_MENU_INFO_FLAGS_IS_SHOWING) {
DEBUG debug_output ("M","Menu: hiding menus\n");
regs.r[1] = -1;
_kernel_swi (Wimp_CreateMenu, &regs, &regs);
}
/* deregister object module */
regs.r[0] = 0;
regs.r[1] = Menu_ObjectClass;
_kernel_swi(Toolbox_DeRegisterObjectModule, &regs, &regs);
/*
* free up memory we may have left allocated
*/
DEBUG debug_output ("M","Menu: exiting\n");
mem_free_all ();
#ifdef ROM
if(!__ROM) _swix(0xa2c41, 0);
#endif
return NULL;
}
/* ++++++++++++++++++++++++++++++++ initialisation code +++++++++++++++++++++++++++++++ */
extern _kernel_oserror *Menu_init(char *cmd_tail, int podule_base, void *pw)
{
char *messages_filename;
_kernel_swi_regs regs;
_kernel_oserror *e;
#ifndef ROM
extern int messages_file(void);
#endif
IGNORE(cmd_tail);
IGNORE(podule_base);
IGNORE(pw);
#ifdef ROM
__ROM = _swix(0xa2c43, _IN(0), pw);
#endif
DEBUG debug_set_var_name("Menu$Debug");
rmensure ("Toolbox", "Toolbox.Toolbox", "1.29");
/*
* register our messages file with Resource FS and MessageTrans
*/
#ifndef ROM
regs.r[0] = messages_file();
if ((e = _kernel_swi (ResourceFS_RegisterFiles, &regs, &regs)) != NULL)
return e;
#endif
DEBUG debug_output ("M","Menu: code initialise\n");
if (getenv ("Menu$Path") == NULL)
messages_filename = "Resources:Resources.Menu.Messages";
else
messages_filename = "Menu:Messages";
if ((e = messages_file_open (messages_filename)) != NULL)
return e;
/* WIMP hack .... explanation follows:
* On RISC OS 3.50 and above a call to Wimp_CreateMenu with 'KEEP' as the menu handle
* (wimp_KeepMenu) will allow menus to stay on screen after an adjust click _even_
* over successive calls to Wimp_Poll. On lower versions, however we merely alter
* a byte in WIMP workspace to do the same thing. This was NOT my idea - TGR
*
* Find out what version of OS it is, if it's lower than 350 then remember workspace
* pointer for future use, if not set the pointer to NULL to indicate its redundance.
*/
regs.r[0] = 7;
if ((e = _kernel_swi (Wimp_ReadSysInfo, &regs, &regs)) != NULL)
return e;
if (regs.r[0] < 350) {
regs.r[0] = os_Module_LookupModuleName;
regs.r[1] = (int) "WindowManager";
if ((e = _kernel_swi (OS_Module, &regs, &regs)) != NULL)
return e;
global_wimp_wrkspc = (int *) regs.r[4]; /* NULL by default (see auxiliary.c) */
}
/* register here with the Toolbox as an Object Module */
regs.r[0] = 0;
regs.r[1] = Menu_ObjectClass;
regs.r[2] = Menu_ClassSWI;
regs.r[3] = 0;
if ((e = _kernel_swi(Toolbox_RegisterObjectModule, &regs, &regs)) != NULL)
return e;
return NULL;
}
/* +++++++++++++++++++++++++++++++++ service handler code ++++++++++++++++++++++++++++++ */
extern void Menu_services(int service_number, _kernel_swi_regs *r, void *pw)
{
_kernel_swi_regs regs;
IGNORE(pw);
DEBUG debug_output ("M","Menu: svc 0x%x\n",service_number);
switch (service_number)
{
case Service_ToolboxTaskDied:
/*
* task dying - r0 holds task handle
*/
task_remove (r->r[0]);
break;
case Service_ToolboxTaskBorn:
/* Toolbox task has just started R0 == wimp task handle */
/*
* create a new "task descriptor"
*/
task_add (r->r[0]);
break;
case Service_ToolboxStarting:
/*
* register with the Toolbox as an Object Module
*/
regs.r[0] = 0;
regs.r[1] = Menu_ObjectClass;
regs.r[2] = Menu_ClassSWI;
regs.r[3] = 0;
_kernel_swi (Toolbox_RegisterObjectModule, &regs, &regs);
break;
default:
break;
}
}
/* ++++++++++++++++++++++++++++++++++++++ SWI code +++++++++++++++++++++++++++++++++++++ */
extern _kernel_oserror *Menu_SWI_handler(int swi_no, _kernel_swi_regs *r, void *pw)
{
_kernel_oserror *e = NULL;
TaskDescriptor *t;
DEBUG debug_output ("M","Menu: SWI 0x%x\n",Menu_SWIChunkBase+swi_no);
IGNORE(pw);
switch (swi_no+Menu_SWIChunkBase)
{
case Menu_ClassSWI:
if (r->r[0] < 0 || r->r[0] >= MAX_CLASS_SWI_METHODS)
{
return make_error_hex(Menu_NoSuchMethod,1,r->r[0]);
}
else
{
t = task_find (r->r[3]);
if (t == NULL)
{
return make_error_hex(Menu_NoSuchTask,1,r->r[3]);
}
DEBUG debug_output ("M","Menu: class SWI method %d\n",r->r[0]);
e = (*class_swi_methods[r->r[0]])(r, t);
}
break;
case Menu_PostFilter:
e = events_postfilter (r);
break;
case Menu_PreFilter:
e = events_prefilter (r);
break;
case Menu_UpdateTree:
e = update_tree ();
break;
default:
break;
}
return e;
}
#if debugging
/* ++++++++++++++++++++++++++++++++++++++ star commands ++++++++++++++++++++++++++++++++++++*/
extern _kernel_oserror *Menu_commands(char *arg_string, int argc, int cmd_no, void *pw)
{
IGNORE(argc);
IGNORE(pw);
IGNORE(arg_string);
switch (cmd_no)
{
case 0:
mem_print_list();
break;
default:
break;
}
return NULL;
}
#endif
/* 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.
*/
/* Title: auxiliary.c
* Purpose: support functions for the Menu object class
* Author: TGR
* History: 1-Nov-93: TGR: created
*
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "kernel.h"
#include "swis.h"
#include "const.h"
#include "macros.h"
#include "services.h"
#include "debug.h"
#include "mem.h"
#include "twimp.h"
#include "os.h"
#include "style.h"
#include "string32.h"
#include "messages.h"
#include "objects.toolbox.h"
#include "objects.menu.h"
#include "Menu.h"
#include "auxiliary.h"
#include "object.h"
#include "task.h"
GlobalMenu global_menu =
{0,0,0,NULL,NULL,NULL};
int *global_wimp_wrkspc = NULL;
EventInterest messages_of_interest[] =
{{wimp_MHELP_REQUEST , 0},
{wimp_MMENUS_DELETED , 0},
{wimp_MMENU_WARNING , 0},
{-1 , -1}
};
EventInterest events_of_interest[] =
{{wimp_EMENU , -1},
{wimp_ETOOLBOX_EVENT , 0},
{-1 , -1}
};
EventInterest toolbox_events_of_interest[] =
{{Menu_AboutToBeShown , 0x828c0},
{-1 , -1}
};
extern _kernel_oserror *menu_update_size(MenuInternal *menu_int) {
wimp_Menu *menu = menu_int->hdr.wimp_menu;
wimp_MenuEntry *entry;
_kernel_swi_regs regs;
_kernel_oserror *e;
int i,mode,
max_width,
width = (menu_int->hdr.wimp_menu->hdr.title.indirect_text.buff_len+1)<<4,
height = 0,
num_entries = menu_int->hdr.num_entries;
max_width=width;
entry=wimp_menu_entry(menu,0);
for (i=0;i<num_entries;i++) {
entry=wimp_menu_entry(menu,i);
if (entry->icon_flags & wimp_ICONFLAGS_TEXT) {
width = (entry->icon_data.indirect_text.buff_len+1)<<4;
} else {
regs.r[0] = os_SpriteOp_ReadInfo;
regs.r[2] = (int) entry->icon_data.indirect_sprite.sprite.name;
if ((e = _kernel_swi (Wimp_SpriteOp, &regs, &regs)) != NULL) {
return e;
}
width = regs.r[3];
mode = regs.r[6];
regs.r[0] = mode;
regs.r[1] = ReadModeVariable_XEigFactor;
if ((e = _kernel_swi (OS_ReadModeVariable, &regs, &regs)) != NULL) {
return e;
}
width = width << regs.r[2];
}
if (width>max_width) max_width=width;
height += ((entry->flags & wimp_MENUFLAGS_DOTTED_LINE) ? 68 : 44);
}
menu_int->hdr.height = height;
menu->hdr.width = max_width;
DEBUG debug_output ("a","Menu: height = %d; width = %d\n",menu_int->hdr.height,menu->hdr.width);
return NULL;
}
#define has_submenu (temp_flags & Menu_Entry_SubMenu)
#define is_sprite (temp_flags & Menu_Entry_IsSprite)
#define dotted_line (temp_flags & Menu_Entry_DottedLine)
#define is_ticked (temp_flags & Menu_Entry_Ticked)
#define is_faded (temp_flags & Menu_Entry_Faded)
#define cause_event (temp_flags & Menu_Entry_GenerateSubMenuEvent)
#define click_trans (temp_flags & Menu_Entry_ClickShowTransient)
extern _kernel_oserror *create_menu_entry(wimp_MenuEntry *entry, MenuTemplateEntry *temp_entry, MenuInternalEntry *int_entry) {
_kernel_swi_regs regs;
_kernel_oserror *e;
int temp_flags = temp_entry->flags;
int text_len = temp_entry->max_text;
int help_len = temp_entry->max_entry_help;
entry->flags =
((is_ticked) ? wimp_MENUFLAGS_TICKED : 0)
| ((dotted_line) ? wimp_MENUFLAGS_DOTTED_LINE : 0)
| ((has_submenu) ? wimp_MENUFLAGS_SUBMENU_MESSAGE : 0);
int_entry->flags =
((cause_event) ? MENU_INT_ENTRY_FLAGS_GENERATE_SUBMENU_EVENT : 0)
| ((click_trans) ? MENU_INT_ENTRY_FLAGS_CLICK_SHOW_TRANSIENT : 0);
/* icon flags: is text?, is sprite?, no border, no Hcentre,
* Vcentre, no filled bgnd, no anti-aliasing, no redraw help,
* indirected?, no Rjustify, same ESG uncancelled, no sprite 1/2,
* (little button type (4bits) = 9,
* endian) ESG (5) = 0, no invert, ? shading, no deleted,
* fgcol (4),
* bgcol (4).
*/
entry->icon_flags = wimp_ICONFLAGS_FORECOL * style_MENU_ENTRY_FORECOL
| wimp_ICONFLAGS_BACKCOL * style_MENU_ENTRY_BACKCOL
| wimp_ICONFLAGS_VCENTRE
| wimp_ICONFLAGS_FILLED
| wimp_ICONFLAGS_INDIRECT
| wimp_ICONFLAGS_NO_CANCEL
| wimp_ICONFLAGS_BUTTON_TYPE * 9
| wimp_ICONFLAGS_ESG * 0
| ((is_faded)?wimp_ICONFLAGS_FADED:0)
| ((is_sprite)?wimp_ICONFLAGS_SPRITE:wimp_ICONFLAGS_TEXT);
DEBUG debug_output ("a","Menu: entry, icon flags = 0x%x\n",entry->icon_flags);
if (is_sprite) {
regs.r[0] = 4;
if ((e = _kernel_swi (Toolbox_GetSysInfo, &regs, &regs)) != NULL)
return e;
entry->icon_data.indirect_sprite.sprite_area = (void *) regs.r[0];
if (text_len == 0 || temp_entry->text == NULL)
return make_error (Menu_NoSpriteName,0);
/* entry->icon_data.indirect_sprite.sprite.name = NULL;*/
else if ((entry->icon_data.indirect_sprite.sprite.name = mem_alloc(text_len)) == NULL) {
return make_error (Menu_AllocFailed,0);
} else {
if (!string_copy_chk (entry->icon_data.indirect_sprite.sprite.name, temp_entry->text,text_len)) {
mem_freek(entry->icon_data.indirect_sprite.sprite.name);
return make_error (Menu_ShortBuffer,0);
}
}
entry->icon_data.indirect_sprite.name_len = string_length (temp_entry->text) + 1;
} else {
entry->icon_data.indirect_text.valid_string = NULL;
if (text_len == 0 || temp_entry->text == NULL)
entry->icon_data.indirect_text.buffer = NULL;
else if ((entry->icon_data.indirect_text.buffer = mem_alloc(text_len)) == NULL) {
return make_error (Menu_AllocFailed,0);
} else {
if (!string_copy_chk (entry->icon_data.indirect_text.buffer, temp_entry->text, text_len)) {
mem_freek(entry->icon_data.indirect_text.buffer);
return make_error (Menu_ShortBuffer,0);
}
}
entry->icon_data.indirect_text.buff_len = string_length (temp_entry->text) + 1;
DEBUG debug_output ("a","String, '%s', text_len, %d, buff_len, %d\n",temp_entry->text,text_len,entry->icon_data.indirect_text.buff_len);
}
if (temp_entry->click_show) { /* create the object */
regs.r[0] = 0;
regs.r[1] = (int) temp_entry->click_show;
if ((e = _kernel_swi (Toolbox_CreateObject, &regs, &regs)) != NULL) {
mem_freek ((is_sprite)?entry->icon_data.indirect_sprite.sprite.name:entry->icon_data.indirect_text.buffer);
return e;
}
int_entry->click_show = (ObjectID) regs.r[0];
} else
int_entry->click_show = NULL;
if (has_submenu) {
entry->submenu = (wimp_Menu *) 0x8000;
if (temp_entry->submenu_show) { /* create the submenu */
regs.r[0] = 0;
regs.r[1] = (int) temp_entry->submenu_show;
if ((e = _kernel_swi (Toolbox_CreateObject, &regs, &regs)) != NULL) {
mem_freek ((is_sprite)?entry->icon_data.indirect_sprite.sprite.name:entry->icon_data.indirect_text.buffer);
return e;
}
int_entry->submenu_show = (ObjectID) regs.r[0];
} else {
int_entry->submenu_show = NULL;
}
} else {
int_entry->submenu_show = NULL;
entry->submenu = (wimp_Menu *) -1;
}
int_entry->text_len = text_len;
int_entry->help_len = help_len;
int_entry->component_id = temp_entry->component_id;
int_entry->submenu_event = temp_entry->submenu_event;
int_entry->click_event = temp_entry->click_event;
if (help_len == 0 || temp_entry->help_message == NULL)
int_entry->help_message=NULL;
else if ((int_entry->help_message = mem_alloc (help_len)) == NULL) {
mem_freek ((is_sprite)?entry->icon_data.indirect_sprite.sprite.name:entry->icon_data.indirect_text.buffer);
return make_error (Menu_AllocFailed,0);
} else {
if (!string_copy_chk (int_entry->help_message,temp_entry->help_message,help_len)) {
mem_freek ((is_sprite)?entry->icon_data.indirect_sprite.sprite.name:entry->icon_data.indirect_text.buffer);
mem_freek(int_entry->help_message);
return make_error (Menu_ShortBuffer,0);
}
}
return NULL;
}
#undef has_submenu
#undef is_sprite
#undef dotted_line
#undef is_ticked
#undef is_faded
#undef cause_event
#undef click_trans
/*
extern _kernel_oserror *copy_menu_entry (wimp_MenuEntry *entry, MenuInternalEntry *int_entry, wimp_MenuEntry *entryx, MenuInternalEntry *int_entryx) {
if (entry->icon_flags | wimp_ICONFLAGS_TEXT) {
if (!entry->icon_data.indirect_text.buffer) {
entryx->icon_data.indirect_text.buffer = NULL;
} else
if ((entryx->icon_data.indirect_text.buffer = mem_alloc(int_entry->text_len)) == NULL) {
return make_error (Menu_AllocFailed,0);
} else
memcpy (entryx->icon_data.indirect_text.buffer, entry->icon_data.indirect_text.buffer, int_entry->text_len);
} else {
if (!entry->icon_data.indirect_sprite.sprite.name) {
entryx->icon_data.indirect_sprite.sprite.name = NULL;
} else
if ((entryx->icon_data.indirect_sprite.sprite.name = mem_alloc(int_entry->text_len)) == NULL) {
return make_error (Menu_AllocFailed,0);
} else
memcpy (entryx->icon_data.indirect_sprite.sprite.name, entry->icon_data.indirect_sprite.sprite.name, int_entry->text_len);
}
if (!int_entry->help_message) {
int_entryx->help_message = NULL;
} else
if ((int_entryx->help_message = mem_alloc (int_entry->help_len)) == NULL) {
return make_error (Menu_AllocFailed,0);
} else strcpy (int_entryx->help_message, int_entry->help_message);
return NULL;
}
*/
void remove_menu_entry (wimp_MenuEntry *entry, MenuInternalEntry *int_entry) {
char *text;
text = (entry->icon_flags & wimp_ICONFLAGS_SPRITE)?entry->icon_data.indirect_sprite.sprite.name:entry->icon_data.indirect_text.buffer;
if (text) mem_freek (text);
if (int_entry->help_message) mem_freek (int_entry->help_message);
}
int find_component (MenuInternal *menu_int, ComponentID component_id) {
int num_entries = menu_int->hdr.num_entries,
i;
for (i = 0; i < num_entries; i++) {
if (component_id == menu_internal_entry(menu_int, i)->component_id)
return i;
}
return -1;
}
extern BOOL menu_showing (MenuInternal *menu_inta) {
_kernel_swi_regs regs;
MenuInternal *menu_intb = global_menu.top;
MenuInternalEntry *int_entryb;
ObjectID submenu,
object_id;
ComponentID component_id;
int buffer[64],
*pposition;
if (menu_intb == menu_inta) {
DEBUG debug_output ("a","Menu: showing top-level\n");
return TRUE;
} else if (menu_intb != NULL) {
DEBUG debug_output ("a","Menu: looking for menu\n");
object_id = global_menu.top->hdr.object_id;
pposition = buffer;
regs.r[0] = 0;
regs.r[1] = (int) buffer;
if (_kernel_swi (Wimp_GetMenuState, &regs, &regs)) {
return FALSE;
}
if (!menu_intb || *pposition == -1) {
return FALSE;
}
while (*(pposition+1) != -1) {
int_entryb = menu_internal_entry (menu_intb,*pposition++);
submenu = int_entryb->submenu_show;
component_id = int_entryb->component_id;
if (!submenu) {
return FALSE;
}
regs.r[0] = 0;
regs.r[1] = (int) submenu;
if (_kernel_swi (Toolbox_GetInternalHandle, &regs, &regs)) {
return FALSE;
}
menu_intb = (MenuInternal *) regs.r[0];
DEBUG debug_output ("a","Menu: got 0x%x\n",(int)menu_intb);
regs.r[0] = 0;
regs.r[1] = (int) submenu;
if (_kernel_swi (Toolbox_GetObjectClass, &regs, &regs)) {
return FALSE;
}
if (regs.r[0] != Menu_ObjectClass) return FALSE;
if (menu_intb == menu_inta) {
DEBUG debug_output ("a","Menu: found subsidiary\n");
return TRUE;
}
}
}
return FALSE;
}
extern _kernel_oserror *update_tree (void) {
_kernel_oserror *e;
_kernel_swi_regs regs;
DEBUG debug_output ("a","Menu: trying to keep menu tree\n");
if (global_wimp_wrkspc) {
global_wimp_wrkspc[208] = 0;
} else {
regs.r[1] = wimp_KeepMenu;
if ((e = _kernel_swi (Wimp_CreateMenu, &regs, &regs)) != NULL)
return e;
}
if ((global_menu.current = global_menu.top) != NULL) {
DEBUG debug_output ("a","Menu: preparing to show global_menu.top = 0x%x\n",global_menu.top);
global_menu.flags |= GLOBAL_MENU_INFO_FLAGS_SHOW_NEXT;
}
return NULL;
}
extern _kernel_oserror *query_update_tree(MenuInternal *d)
{
if (menu_showing(d)) return update_tree();
else return NULL;
}
_kernel_oserror *menu_show_actual (void) {
_kernel_swi_regs regs;
/* Added by NK to cope with showing zero entry menus */
if (global_menu.top->hdr.num_entries == 0) {
char tmm [sizeof(wimp_Menu) + sizeof(wimp_MenuEntry)] ;
wimp_Menu *tm = (wimp_Menu *)tmm;
wimp_MenuEntry *te = (wimp_MenuEntry *) (tm+1);
memcpy(tm,global_menu.top->hdr.wimp_menu,sizeof(wimp_Menu));
tm->hdr.height = 0;
te->icon_flags = 0;
te->flags = wimp_MENUFLAGS_LAST_ITEM | wimp_MENUFLAGS_TITLE_INDIRECT;
regs.r[1] = (int) tm; /* Wimp menu block */
regs.r[2] = global_menu.x;
regs.r[3] = global_menu.y;
DEBUG debug_output ("e","Menu: showing menu, 0x%x (0x%x)\n",global_menu.top,global_menu.top->hdr.object_id);
return _kernel_swi (Wimp_CreateMenu, &regs, &regs);
}
regs.r[1] = (int) global_menu.top->hdr.wimp_menu; /* Wimp menu block */
regs.r[2] = global_menu.x;
regs.r[3] = global_menu.y;
DEBUG debug_output ("e","Menu: showing menu, 0x%x (0x%x)\n",global_menu.top,global_menu.top->hdr.object_id);
return _kernel_swi (Wimp_CreateMenu, &regs, &regs);
}
_kernel_oserror *menu_show_submenu_actual (void) {
_kernel_swi_regs regs;
/* Copied zero length menu hack from above */
if (global_menu.current->hdr.num_entries == 0) { /* build up new menu on heap - 1 zero height entry */
char tmm [sizeof(wimp_Menu) + sizeof(wimp_MenuEntry)] ;
wimp_Menu *tm = (wimp_Menu *)tmm;
wimp_MenuEntry *te = (wimp_MenuEntry *) (tm+1);
memcpy(tm,global_menu.top->hdr.wimp_menu,sizeof(wimp_Menu));
tm->hdr.height = 0;
te->icon_flags = 0;
te->flags = wimp_MENUFLAGS_LAST_ITEM | wimp_MENUFLAGS_TITLE_INDIRECT;
regs.r[1] = (int) tm; /* Wimp menu block */
regs.r[2] = global_menu.x;
regs.r[3] = global_menu.y;
DEBUG debug_output ("e","Menu: showing submenu, 0x%x\n",global_menu.current->hdr.object_id);
return _kernel_swi (Wimp_CreateSubMenu, &regs, &regs);
}
regs.r[1] = (int) global_menu.current->hdr.wimp_menu; /* Wimp menu block */
regs.r[2] = global_menu.x;
regs.r[3] = global_menu.y;
DEBUG debug_output ("e","Menu: showing submenu, 0x%x\n",global_menu.current->hdr.object_id);
return _kernel_swi (Wimp_CreateSubMenu, &regs, &regs);
}
extern _kernel_oserror *has_been_hidden (void) {
_kernel_oserror *e;
_kernel_swi_regs regs;
ToolboxEvent toolbox_event;
if (global_menu.top->hdr.flags & MENU_INT_FLAGS_GENERATE_HIDE_EVENT) {
if (global_menu.top->hdr.hide_event) {
toolbox_event.hdr.event_code = global_menu.top->hdr.hide_event;
} else {
toolbox_event.hdr.event_code = Menu_HasBeenHidden;
}
toolbox_event.hdr.size = sizeof (Menu_HasBeenHidden_Event);
toolbox_event.hdr.flags = 0;
regs.r[0] = 0;
regs.r[1] = global_menu.top->hdr.object_id;
regs.r[2] = -1;
regs.r[3] = (int) &toolbox_event;
if ((e = _kernel_swi (Toolbox_RaiseToolboxEvent, &regs, &regs)) != NULL)
return e;
}
global_menu.top = NULL;
global_menu.current = NULL;
global_menu.flags &= ~GLOBAL_MENU_INFO_FLAGS_IS_SHOWING;
return NULL;
}
/*
void write_back_wimp_menu (ObjectID object_id, wimp_Menu *wimp_menu) {
_kernel_oserror *e;
_kernel_swi_regs regs;
ObjectID parent_id;
ComponentID parent_component;
int position;
MenuInternal *menu_int;
regs.r[0] = 0;
regs.r[1] = object_id;
if (_kernel_swi (Toolbox_GetParent, &regs, &regs)) return;
if ((parent_id = regs.r[0]) == 0) return;
parent_component = regs.r[1];
regs.r[1] = parent_id;
regs.r[0] = 0;
if ((e = _kernel_swi (Toolbox_GetObjectClass, &regs, &regs)) != NULL) {
raise_toolbox_oserror (e, parent_id, -1);
return;
}
if (regs.r[0] != Menu_ObjectClass) return;
regs.r[0] = 0;
regs.r[1] = parent_id;
if ((e = _kernel_swi (Toolbox_GetInternalHandle, &regs, &regs)) != NULL) {
raise_toolbox_oserror (e, parent_id, -1);
return;
}
menu_int = (MenuInternal *) regs.r[0];
if ((position = find_component (menu_int, parent_component)) == -1)
return;
DEBUG debug_output ("a","Menu: writing back to parent (0x%x), component 0x%x at position %d, menu (wimp) 0x%x\n", parent_id, parent_component, position, wimp_menu);
(wimp_menu_entry (menu_int->hdr.wimp_menu, position))->submenu = wimp_menu;
}
*/
/* 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.
*/
/* Title: copy.c
* Purpose: copy a Menu Object
* Author: TGR
* History: 10-Nov-93: TGR: created
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "kernel.h"
#include "swis.h"
#include "const.h"
#include "macros.h"
#include "services.h"
#include "debug.h"
#include "mem.h"
#include "string32.h"
#include "messages.h"
#include "objects.toolbox.h"
#include "objects.menu.h"
#include "auxiliary.h"
#include "Menu.h"
#include "object.h"
#include "task.h"
#include "copy.h"
extern _kernel_oserror *copy_menu (_kernel_swi_regs *r, TaskDescriptor *t)
{
/*
* request to copy an object
* R0 = 2
* R1 = new Object ID
* R2 = internal handle returned when "src" Object was created
* R3 = wimp task handle of caller (use to identify task descriptor)
* R4 -> user regs R0-R9:
* R0 = flags
* bit 0 set => non-recursively copy the Object
* R1 = source Object ID
*/
/*
* The Toolbox has already checked that this is not just a copy
* call for a shared Object which already exists.
* We create a new Object, and add it to the list of Objects for this
* task.
* We need to remember the ObjectID passed to us by the Toolbox, so
* that we can identify this Object if we are given an ID from the
* client's "id block".
*/
#ifdef COPY_OBJECT
MenuInternal *menu_int = (MenuInternal *) r->r[2];
MenuInternal *menu_intx;
MenuInternalEntry *int_entry,
*int_entryx,
*int_entriesx,
*int_entries = menu_int->hdr.entries;
wimp_Menu *menu = menu_int->hdr.wimp_menu;
wimp_Menu *menux;
wimp_MenuEntry *menu_entry,
*menu_entryx;
_kernel_swi_regs *user_regs = ((_kernel_swi_regs *) r->r[4]),
regs;
_kernel_oserror *e = NULL;
ObjectID object_idx = (ObjectID) r->r[1];
int num_entries = menu_int->hdr.num_entries,
i;
size_t menu_size = sizeof(wimp_Menu) + num_entries*sizeof(wimp_MenuEntry),
int_hdr_size = sizeof(MenuInternal),
int_ent_size = num_entries*sizeof(MenuInternalEntry);
DEBUG debug_output ("c","Menu: no. of entries = %d\n",num_entries);
if ((menux=mem_alloc(sizeof(wimp_Menu)+(num_entries)*sizeof(wimp_MenuEntry))) == NULL)
return make_error(Menu_AllocFailed,0);
if ((menu_intx=mem_alloc(sizeof(MenuInternal))) == NULL) {
e = make_error(Menu_AllocFailed,0);
goto clearup5;
}
if ((int_entriesx=mem_alloc((num_entries)*sizeof(MenuInternalEntry))) == NULL) {
e = make_error (Menu_AllocFailed,0);
goto clearup4;
}
user_regs->r[0] = (int) menu_intx;
memcpy (menux, menu, menu_size);
memcpy (menu_intx, menu_int, int_hdr_size);
memcpy (int_entriesx, int_entries, int_ent_size);
if ((menux->hdr.title.indirect_text.buffer = mem_alloc (menu_int->hdr.title_len)) == NULL) {
e = make_error(Menu_AllocFailed,0);
goto clearup3;
}
if ((menu_intx->hdr.help_message = mem_alloc (menu_int->hdr.help_len)) == NULL) {
e = make_error(Menu_AllocFailed,0);
goto clearup2;
}
memcpy (menux->hdr.title.indirect_text.buffer,menu->hdr.title.indirect_text.buffer,menu->hdr.title.indirect_text.buff_len);
strcpy (menu_intx->hdr.help_message,menu_int->hdr.help_message);
menu_intx->hdr.wimp_menu = menux;
menu_intx->hdr.object_id = object_idx;
menu_intx->hdr.entries = int_entriesx;
for (i=0; i<num_entries; i++) {
DEBUG debug_output ("c", "Menu: entry no. %d\n",i);
menu_entry = wimp_menu_entry(menu,i);
int_entry = menu_internal_entry(menu_int,i);
menu_entryx = wimp_menu_entry(menux,i);
int_entryx = menu_internal_entry(menu_intx,i);
if ((e = copy_menu_entry (menu_entry, int_entry, menu_entryx, int_entryx)) != NULL) break;
}
if (e) {
for (i--;i>=0;i--)
remove_menu_entry(wimp_menu_entry(menux,i),menu_internal_entry(menu_intx,i));
goto clearup1;
}
menu_intx->hdr.forward = t->object_list;
menu_intx->hdr.backward = t->object_list->hdr.backward;
t->object_list->hdr.backward->hdr.forward = menu_intx;
t->object_list->hdr.backward = menu_intx;
if (!(user_regs->r[0]&1)) { /* Recursive duplication */
DEBUG debug_output ("c","Menu: recursive copy\n");
for (i=0; i<menu_int->hdr.num_entries; i++) {
int_entry = menu_internal_entry (menu_int, i);
if (int_entry->submenu_show) {
regs.r[0] = user_regs->r[0];
regs.r[1] = (int) int_entry->submenu_show;
if ((e = _kernel_swi (Toolbox_CopyObject, &regs, &regs)) != NULL)
return e;
int_entry = menu_internal_entry (menu_intx, i);
int_entry->submenu_show = (ObjectID) regs.r[0];
}
}
}
r->r[0] = (int) menu_intx;
IGNORE(t);
return NULL;
clearup1:
if (menu_intx->hdr.help_message) mem_freek(menu_intx->hdr.help_message);
clearup2:
if (menux->hdr.title.indirect_text.buffer) mem_freek(menux->hdr.title.indirect_text.buffer);
clearup3:
mem_freek(int_entriesx);
clearup4:
mem_freek(menu_intx);
clearup5:
mem_freek(menux);
return e;
#else
return NULL;
#endif
}
/* 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.
*/
/* Title: create.c
* Purpose: create a Menu Object
* Author: TGR
* History: 1-Nov-93: TGR
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stddef.h>
#include "kernel.h"
#include "swis.h"
#include "const.h"
#include "macros.h"
#include "string32.h"
#include "messages.h"
#include "objects.toolbox.h"
#include "objects.menu.h"
#include "services.h"
#include "debug.h"
#include "mem.h"
#include "twimp.h"
#include "style.h"
#include "Menu.h"
#include "auxiliary.h"
#include "object.h"
#include "task.h"
#include "create.h"
_kernel_oserror *create_menu_aux (MenuTemplate *menu_temp, ObjectID object_id, TaskDescriptor *t, MenuInternal *menu_int, MenuTemplateEntry *temp_entries);
extern _kernel_oserror *create_menu (_kernel_swi_regs *r, TaskDescriptor *t) {
/*
* request to create a menu
* R0 = 0
* R1 = Object ID
* R2 = 0 (will be internal handle for other SWIs
* R3 = wimp task handle of caller (use to identify task descriptor)
* R4 -> user regs R0-R9
* R0 = flags
* R1 -> description block
*/
/*
* The Toolbox has already checked that this is not just a create
* call for a shared Object which already exists.
* We create a new Object, and add it to the list of Objects for this
* task.
* We need to remember the ObjectID passed to us by the Toolbox, so
* that we can identify this Object if we are given an ID from the
* client's "id block".
* Note that if any template names are held in the Object, then we
* create an Object from that template, and store its ID.
* Note also that the Toolbox has changed the client's R1 to point
* at an in-core template, if it wasn't already!
*/
_kernel_swi_regs *user_regs;
MenuTemplate *menu_temp,
*new_menu_temp = NULL;
MenuTemplateEntry *temp_entries;
ObjectTemplateHeader *obj_temp_hdr;
MenuInternal *menu_int;
ObjectID object_id;
int version_no;
_kernel_oserror *e;
user_regs = (_kernel_swi_regs *) r->r[4];
obj_temp_hdr = (ObjectTemplateHeader *)user_regs->r[1];
menu_temp = (MenuTemplate *) obj_temp_hdr->body;
object_id = (ObjectID) r->r[1];
version_no = obj_temp_hdr->version;
if ((menu_int=mem_alloc(sizeof(MenuInternal))) == NULL) {
return make_error(Menu_AllocFailed,0);
}
/* Version 100 menus are not supported AT ALL - none should exist and if they do,
* they'll crash the application */
if (version_no == 101) { /* if more versions are added, change to switch statement */
if ((new_menu_temp = mem_alloc (sizeof (MenuTemplate))) == NULL) {
mem_freek (menu_int);
return make_error (Menu_AllocFailed, 0);
}
DEBUG debug_output (
"f",
"Menu: old version, copying 0x%x (size 0x%x) to 0x%x and 0x%x (size 0x%x) to 0x%x\n",
menu_temp,
offsetof (MenuTemplateHeader,show_event),
new_menu_temp,
((char *) menu_temp) + offsetof (MenuTemplateHeader101,num_entries),
(sizeof (MenuTemplateHeader) - offsetof (MenuTemplateHeader, num_entries)),
((char *) new_menu_temp) + offsetof (MenuTemplateHeader,num_entries)
);
memcpy (new_menu_temp,
menu_temp,
offsetof (MenuTemplateHeader,show_event)
);
memcpy (((char *) new_menu_temp) + offsetof (MenuTemplateHeader ,num_entries),
((char *) menu_temp) + offsetof (MenuTemplateHeader101,num_entries),
(sizeof (MenuTemplateHeader) - offsetof (MenuTemplateHeader, num_entries))
);
new_menu_temp->hdr.show_event = 0;
new_menu_temp->hdr.hide_event = 0;
temp_entries = (MenuTemplateEntry *) (((MenuTemplateHeader101 *) menu_temp)+1);
menu_temp = new_menu_temp;
} else {
temp_entries = (MenuTemplateEntry *) (menu_temp + 1);
}
DEBUG debug_output ("f","Menu: using first template menu entry at 0x%x\n",temp_entries);
if ((e = create_menu_aux (menu_temp, object_id, t, menu_int, temp_entries)) != NULL) {
if (new_menu_temp) mem_freek (new_menu_temp);
mem_freek(menu_int);
return e;
}
user_regs->r[0] = r->r[1];
r->r[0] = (int) menu_int;
if (new_menu_temp) mem_freek (new_menu_temp);
return NULL;
}
_kernel_oserror *create_menu_aux (MenuTemplate *menu_temp, ObjectID object_id, TaskDescriptor *t, MenuInternal *menu_int, MenuTemplateEntry *temp_entries) {
_kernel_oserror *e = NULL;
_kernel_swi_regs regs;
MenuTemplateEntry *temp_entry;
MenuInternalEntry *int_entry,*int_entries;
wimp_Menu *menu;
wimp_MenuEntry *menu_entry;
int num_entries;
int i;
BOOL generate_show_event = menu_temp->hdr.flags & Menu_GenerateShowEvent;
BOOL generate_hide_event = menu_temp->hdr.flags & Menu_GenerateHideEvent;
num_entries = menu_temp->hdr.num_entries;
DEBUG debug_output ("M","Menu: auxiliary create, num_entries = %d\n",num_entries);
if ((menu=mem_alloc(sizeof(wimp_Menu) + num_entries*sizeof(wimp_MenuEntry))) == NULL) {
return make_error(Menu_AllocFailed,0);
}
menu_int->hdr.wimp_menu = menu;
DEBUG debug_output ("M","Menu, max title_len = %d, title = '%s'\n",menu_temp->hdr.max_title,menu_temp->hdr.title);
if (!menu_temp->hdr.title || !menu_temp->hdr.max_title) {
menu->hdr.title.indirect_text.buffer = NULL;
menu->hdr.title.indirect_text.buff_len = 0;
} else if ((menu->hdr.title.indirect_text.buffer = mem_alloc(menu_temp->hdr.max_title)) == NULL) {
e = make_error(Menu_AllocFailed,0);
goto clearup5;
} else if (!string_copy_chk(menu->hdr.title.indirect_text.buffer,menu_temp->hdr.title,menu_temp->hdr.max_title)) {
e = make_error (Menu_ShortBuffer,0);
goto clearup4;
} else {
menu->hdr.title.indirect_text.valid_string = NULL;
menu->hdr.title.indirect_text.buff_len = strlen (menu_temp->hdr.title) + 1;
}
if (num_entries) {
if ((int_entries=mem_alloc(num_entries*sizeof(MenuInternalEntry))) == NULL) {
e = make_error(Menu_AllocFailed,0);
goto clearup4;
}
}
else
int_entries = NULL;
menu_int->hdr.entries = int_entries;
if (menu_temp->hdr.max_help) {
if ((menu_int->hdr.help_message = mem_alloc(menu_temp->hdr.max_help)) == NULL) {
e = make_error(Menu_AllocFailed,0);
goto clearup3;
} else string_copy_chk (menu_int->hdr.help_message,menu_temp->hdr.help_message,menu_temp->hdr.max_help);
}
else menu_int->hdr.help_message = NULL;
menu->hdr.title_fgnd = style_MENU_TITLE_FORECOL;
menu->hdr.title_bgnd = style_MENU_TITLE_BACKCOL;
menu->hdr.worka_fgnd = style_MENU_ENTRY_FORECOL;
menu->hdr.worka_bgnd = style_MENU_ENTRY_BACKCOL;
menu->hdr.height = style_MENU_ENTRY_HEIGHT;
menu->hdr.vert_gap = style_MENU_ENTRY_GAP;
menu_int->hdr.object_id = object_id;
menu_int->hdr.flags = (generate_show_event ? MENU_INT_FLAGS_GENERATE_SHOW_EVENT : 0)
| (generate_hide_event ? MENU_INT_FLAGS_GENERATE_HIDE_EVENT : 0);
menu_int->hdr.num_entries = num_entries;
menu_int->hdr.title_len = menu_temp->hdr.max_title;
menu_int->hdr.help_len = menu_temp->hdr.max_help;
menu_int->hdr.show_event = menu_temp->hdr.show_event;
menu_int->hdr.hide_event = menu_temp->hdr.hide_event;
for (i=0; i<num_entries; i++) {
DEBUG debug_output ("f", "Menu: entry no. %d\n",i);
menu_entry = wimp_menu_entry(menu,i);
temp_entry = &(temp_entries[i]); /*menu_template_entry(menu_temp,i);*/
int_entry = menu_internal_entry(menu_int,i);
if ((e = create_menu_entry (menu_entry, temp_entry, int_entry)) != NULL) break;
}
if (e) {
for (i--;i>=0;i--)
remove_menu_entry(wimp_menu_entry(menu,i),menu_internal_entry(menu_int,i));
goto clearup2;
}
if (num_entries>0) {
wimp_menu_entry(menu,0)->flags |= wimp_MENUFLAGS_TITLE_INDIRECT;
wimp_menu_entry(menu,num_entries-1)->flags |= wimp_MENUFLAGS_LAST_ITEM;
}
if ((e = menu_update_size(menu_int)) != NULL) {
goto clearup1;
}
if (t->object_list) { /* If there are already menus attached to the task ... */
menu_int->hdr.forward = t->object_list;
menu_int->hdr.backward = t->object_list->hdr.backward;
t->object_list->hdr.backward->hdr.forward = menu_int;
t->object_list->hdr.backward = menu_int;
} else { /* ... if not ... */
/* register interest in toolbox events */
regs.r[0] = 0;
regs.r[1] = Menu_PostFilter;
regs.r[2] = (int) t;
regs.r[3] = Toolbox_RegisterPostFilter_ToolboxEvent;
regs.r[4] = (int) toolbox_events_of_interest;
if ((e = _kernel_swi (Toolbox_RegisterPostFilter, &regs, &regs)) != NULL) {
goto clearup1;
}
/* register interest in wimp events */
regs.r[0] = 0;
regs.r[1] = Menu_PostFilter;
regs.r[2] = (int) t;
regs.r[3] = Toolbox_RegisterPostFilter_WimpEvent;
regs.r[4] = (int) events_of_interest;
if ((e = _kernel_swi (Toolbox_RegisterPostFilter, &regs, &regs)) != NULL) {
goto clearup1;
}
/* register interest in wimp messages */
regs.r[0] = 0;
regs.r[1] = Menu_PostFilter;
regs.r[2] = (int) t;
regs.r[3] = Toolbox_RegisterPostFilter_WimpMessage;
regs.r[4] = (int) messages_of_interest;
if ((e = _kernel_swi (Toolbox_RegisterPostFilter, &regs, &regs)) != NULL) {
goto clearup1;
}
/* register interest in pre-filter */
regs.r[0] = 0;
regs.r[1] = Menu_PreFilter;
regs.r[2] = (int) t;
if ((e = _kernel_swi (Toolbox_RegisterPreFilter, &regs, &regs)) != NULL) {
goto clearup1;
}
t->object_list = menu_int;
menu_int->hdr.forward = menu_int;
menu_int->hdr.backward = menu_int;
}
return e;
clearup1:
for (i=0; i<num_entries; i++) {
remove_menu_entry(wimp_menu_entry(menu,i),menu_internal_entry(menu_int,i));
}
clearup2:
if (menu_int->hdr.help_message) mem_freek(menu_int->hdr.help_message);
clearup3:
mem_freek(int_entries);
clearup4:
if (menu->hdr.title.indirect_text.buffer) mem_freek(menu->hdr.title.indirect_text.buffer);
clearup5:
mem_freek(menu);
return e;
}
/* 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.
*/
/* Title: delete.c
* Purpose: delete a Menu Object
* Author: TGR
* History: 3-Nov-93: TGR: created
*
*/
#include <stdio.h>
#include <stdlib.h>
#include "kernel.h"
#include "swis.h"
#include "const.h"
#include "macros.h"
#include "string32.h"
#include "messages.h"
#include "objects.toolbox.h"
#include "objects.menu.h"
#include "services.h"
#include "debug.h"
#include "mem.h"
#include "auxiliary.h"
#include "Menu.h"
#include "object.h"
#include "task.h"
#include "hide.h"
#include "delete.h"
extern _kernel_oserror *delete_menu (_kernel_swi_regs *r, TaskDescriptor *t)
{
/*
* request to delete an object
* R0 = 1
* R1 = Object ID
* R2 = internal handle returned when Object was created
* R3 = wimp task handle of caller (use to identify task descriptor)
* R4 -> user regs R0-R9
* R0 = flags
* R1 = Object ID
*/
/*
* The Toolbox has already checked that this is not just a delete
* call for a shared Object.
* We delete Object from the list of Objects for this
* task.
* If recursive delete is requested then we also call Toolbox_Delete
* for any Objects "attached" to this Object.
*/
_kernel_swi_regs *user_regs = (_kernel_swi_regs *) r->r[4],
regs;
_kernel_oserror *l,*e = NULL;
MenuInternal *menu_int = (MenuInternal *) r->r[2];
MenuInternalEntry *int_entry;
int i;
DEBUG debug_output ("d","Menu: Entering delete with internal menu handle = 0x%x\n",(int) menu_int);
if (menu_showing(menu_int)) {
DEBUG debug_output ("d","Menu: hiding menus\n");
regs.r[1] = -1;
_kernel_swi (Wimp_CreateMenu, &regs, &regs);
has_been_hidden ();
}
if (!(user_regs->r[0]&Toolbox_DeleteObject_DontRecurse)) { /* Recursive deletion */
DEBUG debug_output ("d","Menu: recursive deletion, no. of entries = %d\n",menu_int->hdr.num_entries);
for (i=0; i<menu_int->hdr.num_entries; i++) {
int_entry = menu_internal_entry (menu_int, i);
DEBUG debug_output ("d","Menu: entry %d's submenu = 0x%x\n",i,(int)int_entry->submenu_show);
if (int_entry->submenu_show) {
regs.r[0] = user_regs->r[0];
regs.r[1] = (int) int_entry->submenu_show;
if ((l = _kernel_swi (Toolbox_DeleteObject, &regs, &regs)) != NULL)
/* If an error occurs in deletion, we get out of the loop ...*/
e=l;
}
if (int_entry->click_show) {
regs.r[0] = user_regs->r[0];
regs.r[1] = (int) int_entry->click_show;
if ((l = _kernel_swi (Toolbox_DeleteObject, &regs, &regs)) != NULL)
/* If an error occurs in deletion, we get out of the loop ...*/
e=l;
}
}
}
DEBUG debug_output ("d","Menu: immediately after recursive delete routine\n");
if (menu_int->hdr.forward == menu_int) { /* Unlinking from the list is regarded as imperative */
DEBUG debug_output ("d","Menu: about to register disinterest\n");
regs.r[0] = 1; /* No longer interested in events */
regs.r[1] = Menu_PostFilter;
regs.r[2] = (int) t;
regs.r[3] = Toolbox_RegisterPostFilter_ToolboxEvent;
regs.r[4] = (int) toolbox_events_of_interest;
_kernel_swi (Toolbox_RegisterPostFilter, &regs, &regs);
regs.r[0] = 1; /* No longer interested in events */
regs.r[1] = Menu_PostFilter;
regs.r[2] = (int) t;
regs.r[3] = Toolbox_RegisterPostFilter_WimpEvent;
regs.r[4] = (int) events_of_interest;
_kernel_swi (Toolbox_RegisterPostFilter, &regs, &regs);
regs.r[0] = 1; /* No longer interested in events */
regs.r[1] = Menu_PostFilter;
regs.r[2] = (int) t;
regs.r[3] = Toolbox_RegisterPostFilter_WimpMessage;
regs.r[4] = (int) messages_of_interest;
_kernel_swi (Toolbox_RegisterPostFilter, &regs, &regs);
regs.r[0] = 1;
regs.r[1] = Menu_PreFilter;
regs.r[2] = (int) t;
_kernel_swi (Toolbox_RegisterPreFilter, &regs, &regs);
t->object_list = NULL;
} else {
if (t->object_list == menu_int) {
t->object_list = menu_int->hdr.forward;
}
menu_int->hdr.forward->hdr.backward = menu_int->hdr.backward;
menu_int->hdr.backward->hdr.forward = menu_int->hdr.forward;
}
for (i=0; i<menu_int->hdr.num_entries; i++) {
remove_menu_entry(wimp_menu_entry(menu_int->hdr.wimp_menu,i),menu_internal_entry(menu_int,i));
}
if (menu_int->hdr.wimp_menu->hdr.title.indirect_text.buffer)
mem_freek (menu_int->hdr.wimp_menu->hdr.title.indirect_text.buffer);
mem_freek (menu_int->hdr.wimp_menu);
if (menu_int->hdr.entries) mem_freek (menu_int->hdr.entries);
if (menu_int->hdr.help_message) mem_freek (menu_int->hdr.help_message);
mem_freek (menu_int);
return e;
}
/* 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.
*/
/* Title: events.c
* Purpose: filters registered with the Toolbox. Events are delivered here.
* Author: TGR
* History: 17-Nov-93: TGR: created
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "kernel.h"
#include "swis.h"
#include "const.h"
#include "macros.h"
#include "string32.h"
#include "messages.h"
#include "objects.toolbox.h"
#include "objects.menu.h"
#include "services.h"
#include "debug.h"
#include "mem.h"
#include "auxiliary.h"
#include "Menu.h"
#include "events.h"
_kernel_oserror *event_help_request (wimp_Message message_block, TaskDescriptor *t);
_kernel_oserror *event_menu_warning (wimp_Message message_block, TaskDescriptor *t);
_kernel_oserror *event_menus_deleted (wimp_Message message_block, TaskDescriptor *t);
_kernel_oserror *event_menu_selection (int *menu_tree, TaskDescriptor *t, IDBlock *id_block,_kernel_swi_regs *r);
_kernel_oserror *event_menu_to_show (TaskDescriptor *t, IDBlock *id_block,_kernel_swi_regs *r);
extern _kernel_oserror *events_postfilter (_kernel_swi_regs *r)
{
/*
* called from the main Toolbox postfilter, when an event happens which
* this module has expressed an interest in.
* R0 = Wimp event reason code
* R1 ->client's Wimp event block
* R2 = Task Descriptor of task interested in the event
* R3 ->6-word "ID block" as passed to Toolbox_Initialise
*
*/
/*
* This function gets a pointer to the task interested in the event in
* R2 (since this was the value passed to Toolbox_RegisterPostFilter).
* If the event is dealt with by this module (eg ID block gets updated).
* then set R0 to non-null before return.
*/
wimp_PollBlock *block = (wimp_PollBlock *)r->r[1];
IDBlock *id_block = (IDBlock *)r->r[3];
int event_code = r->r[0];
TaskDescriptor *t = (TaskDescriptor *) r->r[2];
DEBUG debug_output ("e","Menu: Postfilter entered, received wimp event code = 0x%x\n",event_code);
DEBUG {
_kernel_swi_regs regs;
char buffer[256];
int i;
regs.r[0] = 0;
regs.r[1] = (int)buffer;
_kernel_swi (Wimp_GetMenuState, &regs, &regs);
for (i=0; *((int *)buffer+i)!=-1; i++)
debug_output ("e","Menu: state (entry %d) %d\n",i,*((int *)buffer + i));
}
r->r[0] = 0;
if (t == NULL)
return NULL;
switch (event_code) {
case wimp_ESEND:
case wimp_ESEND_WANT_ACK:
switch (block->msg.hdr.action) {
case wimp_MMENUS_DELETED:
return event_menus_deleted(block->msg,t);
break;
case wimp_MMENU_WARNING:
return event_menu_warning(block->msg,t);
break;
case wimp_MHELP_REQUEST:
return event_help_request(block->msg,t);
break;
default:
break;
}
break;
case wimp_EMENU:
return event_menu_selection((int *) r->r[1],t,id_block,r);
/* ... R1 points to a list of menu selections */
break;
case wimp_ETOOLBOX_EVENT:
DEBUG debug_output ("e","Menu: handling a toolbox event, code = 0x%x\n",block->toolbox_event.hdr.event_code);
if (block->toolbox_event.hdr.event_code == Menu_AboutToBeShown)
return event_menu_to_show (t,id_block,r);
break;
default:
break;
}
return NULL;
}
extern _kernel_oserror *events_prefilter (_kernel_swi_regs *r)
{
/*
* called from the main Toolbox prefilter, when Wimp_Poll is called.
* R0 = mask passed to Wimp_Poll
* R1 ->client's poll block passed to Wimp_Poll
* R2 = Task Descriptor.
*
*/
/*
* This function gets a pointer to the current task in
* R2 (since this was the value passed to Toolbox_RegisterPreFilter).
* This function can enable additional events by zero-ing bits in
* r->r[0]
*/
_kernel_oserror *e;
DEBUG debug_output ("e","Menu: prefilter entered\n");
DEBUG {
_kernel_swi_regs regs;
char buffer[256];
int i;
regs.r[0] = 0;
regs.r[1] = (int)buffer;
_kernel_swi (Wimp_GetMenuState, &regs, &regs);
for (i=0; *((int *)buffer+i)!=-1; i++)
debug_output ("e","Menu: state (entry %d) %d\n",i,*((int *)buffer + i));
}
if (global_menu.flags & GLOBAL_MENU_INFO_FLAGS_SHOW_NEXT) {
global_menu.flags = (global_menu.flags
| GLOBAL_MENU_INFO_FLAGS_IS_SHOWING)
& ~GLOBAL_MENU_INFO_FLAGS_SHOW_NEXT;
if ((e = ((global_menu.current == global_menu.top)?menu_show_actual():menu_show_submenu_actual())) != NULL) {
return e;
}
}
r->r[0] &= ~wimp_EMMENU /* 'EM' stands for 'Event Mask' = 1 << (event number) */
& ~wimp_EMSEND
& ~wimp_EMSEND_WANT_ACK;
return NULL;
}
/*** test code - wimp tree traversal algorithm ***
void traverse (wimp_Menu *menu) {
int i=0;
wimp_MenuEntry *entry;
char *ptr= (char*) menu;
FILE *fp;
debug_output ("e","Menu: Tree traversal:\nfg, %d\nwidth, %d\nheight, %d\n",menu->hdr.title_fgnd,menu->hdr.width,menu->hdr.height);
do {
entry = wimp_menu_entry(menu,i);
debug_output ("e","entry no. %d, text = '%s' (length = %d),icon_flags=0x%x\n",i,entry->icon_data.indirect_text.buffer,entry->icon_data.indirect_text.buff_len,entry->icon_flags);
} while (!(wimp_menu_entry(menu,i++)->flags & wimp_MENUFLAGS_LAST_ITEM));
if ((fp = fopen ("$.dump", "w")) != NULL) {
for (i=0;i<0x400;i++)
putc (*ptr++,fp);
fclose (fp);
}
}
*/
/* Respond to request for help ******************************************************************/
_kernel_oserror *event_help_request (wimp_Message message_block, TaskDescriptor *t) {
_kernel_swi_regs regs;
_kernel_oserror *e;
MenuInternal *menu_int = global_menu.top;
MenuInternalEntry *int_entry;
wimp_Message help_reply;
int buffer[64], /* menu list buffer */
*pposition,
str_len;
ObjectID object_id = global_menu.top->hdr.object_id,
submenu;
ComponentID component_id;
DEBUG debug_output ("e","Menu: request for help\n");
IGNORE(t);
pposition = buffer;
regs.r[0] = 0;
regs.r[1] = (int) buffer;
if ((e = _kernel_swi (Wimp_GetMenuState, &regs, &regs)) != NULL) {
return e;
}
if (!menu_int || *pposition == -1) {
/* We're not handling a menu OR menu tree too short! */
return NULL;
}
while (*(pposition+1) != -1) {
int_entry = menu_internal_entry (menu_int,*pposition++);
submenu = int_entry->submenu_show;
component_id = int_entry->component_id;
if (!submenu) {
return make_error_hex(Menu_UnknownSubMenu,object_id,component_id,2,(int) object_id,(int) component_id);
}
regs.r[0] = 0;
regs.r[1] = (int) submenu;
if ((e = _kernel_swi (Toolbox_GetInternalHandle, &regs, &regs)) != NULL) {
return e;
}
menu_int = (MenuInternal *) regs.r[0];
regs.r[0] = 0;
regs.r[1] = (int) submenu;
if ((e = _kernel_swi (Toolbox_GetObjectClass, &regs, &regs)) != NULL ) {
return e;
}
if (regs.r[0] != Menu_ObjectClass) return NULL;
}
if (object_id == 0) { /* Should this happen? */
return NULL;
} else {
wimp_GetWindowInfo window_info;
wimp_PointerInfo pointer_info;
regs.r[1] = (int) &pointer_info;
if ((e = _kernel_swi (Wimp_GetPointerInfo, &regs, &regs)) != NULL)
return e;
if (pointer_info.window_handle == -1 || pointer_info.window_handle == -2)
return NULL;
window_info.window_handle = pointer_info.window_handle;
regs.r[1] = 1|(int)&window_info;
if ((e = _kernel_swi (Wimp_GetWindowInfo, &regs, &regs)) != NULL)
return e;
if (window_info.window.title.indirect_text.buffer != menu_int->hdr.wimp_menu->hdr.title.indirect_text.buffer)
return NULL;
}
object_id = menu_int->hdr.object_id;
component_id = menu_internal_entry(menu_int, *pposition)->component_id;
help_reply.hdr.your_ref = message_block.hdr.my_ref;
help_reply.hdr.action = wimp_MHELP_REPLY;
help_reply.hdr.size = sizeof(wimp_Message);
if (menu_internal_entry(menu_int,*pposition)->help_message) {
string_copy_chk (help_reply.data.chars, menu_internal_entry(menu_int,*pposition)->help_message, wimp_MAX_MSG_DATA_SIZE);
} else if (menu_int->hdr.help_message) {
string_copy_chk (help_reply.data.chars, menu_int->hdr.help_message, wimp_MAX_MSG_DATA_SIZE);
} else {
return NULL;
}
str_len = strlen(help_reply.data.chars);
if (str_len < wimp_MAX_MSG_DATA_SIZE) {
help_reply.data.chars[str_len+1] = '\0';
if (str_len+1 < wimp_MAX_MSG_DATA_SIZE)
help_reply.data.chars[str_len+2] = '\0';
}
regs.r[0] = wimp_ESEND;
regs.r[1] = (int) &help_reply;
regs.r[2] = message_block.hdr.task_handle;
DEBUG debug_output ("e","Menu: sending help reply\n");
if ((e = _kernel_swi (Wimp_SendMessage, &regs, &regs)) != NULL) {
return e;
}
return NULL;
}
/* Respond to a pointer traversing a submenu arrow **********************************************/
_kernel_oserror *event_menu_warning (wimp_Message message_block, TaskDescriptor *t) {
MenuInternal *menu_int = global_menu.top;
MenuInternalEntry *int_entry;
wimp_MenuEntry *entry;
int *pposition = (int *) message_block.data.menu_warning.data,
submenu_event;
Menu_SubMenu_Event
*menu_sm;
ToolboxEvent toolbox_event;
ObjectID object_id = global_menu.top->hdr.object_id;
ObjectID submenu;
ComponentID component_id;
DisplayInfo *coords;
_kernel_swi_regs regs;
_kernel_oserror *e;
DEBUG debug_output ("e","Menu: event menu warning entered\n");
if (!menu_int || (*pposition == -1)) {
/* We're not handling a menu OR menu tree V.short */
return NULL;
}
while (*(pposition+1) != -1) {
int_entry = menu_internal_entry (menu_int,*pposition++);
submenu = int_entry->submenu_show;
component_id = int_entry->component_id;
if (!submenu) {
return make_error_hex(Menu_UnknownSubMenu,object_id,component_id,2,(int) object_id,(int) component_id);
}
regs.r[0] = 0;
regs.r[1] = (int) submenu;
if ((e = _kernel_swi (Toolbox_GetInternalHandle, &regs, &regs)) != NULL ) {
return e;
}
menu_int = (MenuInternal *) regs.r[0];
regs.r[0] = 0;
regs.r[1] = (int) submenu;
if ((e = _kernel_swi (Toolbox_GetObjectClass, &regs, &regs)) != NULL ) {
return e;
}
if (regs.r[0] != Menu_ObjectClass) return NULL;
}
entry = wimp_menu_entry (menu_int->hdr.wimp_menu, *pposition);
int_entry = menu_internal_entry (menu_int, *pposition);
object_id = menu_int->hdr.object_id;
component_id = int_entry->component_id;
submenu_event = int_entry->submenu_event;
submenu = int_entry->submenu_show;
DEBUG debug_output ("e","Menu: submenu to show = 0x%x\n",submenu);
coords = (DisplayInfo *) &toolbox_event.data;
coords->x = message_block.data.menu_warning.x;
coords->y = message_block.data.menu_warning.y;
toolbox_event.hdr.flags = 0;
if (int_entry->flags & MENU_INT_ENTRY_FLAGS_GENERATE_SUBMENU_EVENT) {
if (submenu_event) {
toolbox_event.hdr.size = sizeof (ToolboxEventHeader);
toolbox_event.hdr.event_code = submenu_event;
} else {
toolbox_event.hdr.size = sizeof (Menu_SubMenu_Event);
toolbox_event.hdr.event_code = Menu_SubMenu;
menu_sm = (Menu_SubMenu_Event *) &toolbox_event;
menu_sm->x = coords->x;
menu_sm->y = coords->y;
}
regs.r[0] = 0;
regs.r[1] = (int) object_id;
regs.r[2] = component_id;
regs.r[3] = (int) &toolbox_event;
DEBUG debug_output ("e","Menu: submenu event, 0x%x\n",submenu_event);
if ((e = _kernel_swi (Toolbox_RaiseToolboxEvent, &regs, &regs)) != NULL) {
return e;
}
}
if (submenu) {
regs.r[0] = 2; /* Show as submenu */
regs.r[1] = (int) submenu;
regs.r[2] = 2; /* R3 points to coords */
regs.r[3] = (int) coords;
regs.r[4] = (int) object_id;
regs.r[5] = component_id;
DEBUG debug_output ("e","Menu: parent object = 0x%x, coords = (%d,%d)\n",object_id,coords->x,coords->y);
if ((e = _kernel_swi (Toolbox_ShowObject, &regs, &regs)) != NULL) {
DEBUG debug_output ("e", "Menu: handling error generated by Toolbox_ShowObject with ID, 0x%x\n",submenu);
return e;
}
DEBUG debug_output ("e","Menu: returned wimp menu value = 0x%x\n",regs.r[0]);
entry->submenu = (wimp_Menu *) (regs.r[0] ? regs.r[0] : 0x8000);
}
IGNORE(t);
DEBUG debug_output ("e","Menu: exiting successfully from event_menu_warning\n");
return NULL;
}
/* Menu will be deleted. Mark it as not showing *************************************************/
_kernel_oserror *event_menus_deleted (wimp_Message message_block, TaskDescriptor *t) {
_kernel_oserror *e;
MenuInternal *menu_int = global_menu.top;
if (!menu_int) { /* We're not handling a menu! */
return NULL;
}
DEBUG debug_output ("e","Menu: menu_int->hdr.wimp_menu @0x%x, message_block wimp_menu @0x%x\n",menu_int->hdr.wimp_menu,*message_block.data.words);
if (menu_int->hdr.wimp_menu != (wimp_Menu *) (*message_block.data.words))
return NULL;
DEBUG debug_output ("e","Menu: menus deleted, tidying up\n");
if ((e = has_been_hidden ()) != NULL)
return e;
IGNORE(t);
IGNORE(message_block);
return NULL;
}
/* Respond to a menu selection ******************************************************************/
_kernel_oserror *event_menu_selection (int *menu_tree, TaskDescriptor *t, IDBlock *id_block, _kernel_swi_regs *r) {
MenuInternal *menu_int = global_menu.top;
MenuInternalEntry *int_entry;
int *pposition = menu_tree;
ObjectID object_id = global_menu.top->hdr.object_id;
ObjectID submenu;
ComponentID component_id;
int click_event;
ObjectID click_show;
ToolboxEvent toolbox_event;
_kernel_swi_regs regs;
_kernel_oserror *e;
wimp_PointerInfo pointer_info;
DEBUG debug_output ("e","Menu: selection entered\n");
if (!menu_int || *pposition == -1) {
DEBUG debug_output ("e","Menu: not much here, returning\n");
/* We're not handling a menu OR menu tree too short! */
return NULL;
}
while (*(pposition+1) != -1) {
DEBUG debug_output ("e","Menu: position %d\n",*pposition);
int_entry = menu_internal_entry (menu_int,*pposition++);
submenu = int_entry->submenu_show;
component_id = int_entry->component_id;
if (!submenu) {
return NULL;
}
regs.r[0] = 0;
regs.r[1] = (int) submenu;
if ((e = _kernel_swi (Toolbox_GetInternalHandle, &regs, &regs)) != NULL ) {
return e;
}
menu_int = (MenuInternal *) regs.r[0];
regs.r[0] = 0;
regs.r[1] = (int) submenu;
if ((e = _kernel_swi (Toolbox_GetObjectClass, &regs, &regs)) != NULL ) {
return e;
}
if (regs.r[0] != Menu_ObjectClass) return NULL;
}
DEBUG debug_output ("e","Menu: final position %d\n",*pposition);
object_id = menu_int->hdr.object_id;
if (id_block->self_id == object_id) return NULL;
regs.r[1] = (int) &pointer_info;
if ((e = _kernel_swi (Wimp_GetPointerInfo, &regs, &regs)) != NULL) {
return e;
}
int_entry = menu_internal_entry (menu_int,*pposition);
if ((pointer_info.button_state & wimp_ADJUST_BUTTON) && (~int_entry->flags & MENU_INT_ENTRY_FLAGS_CLICK_SHOW_TRANSIENT)) {
DEBUG debug_output ("e","Menu: adjust click\n");
if ((e = update_tree ()) != NULL)
return e;
} else if (pointer_info.button_state & (wimp_SELECT_BUTTON|wimp_MENU_BUTTON)) {
if ((e = has_been_hidden ()) != NULL)
return e;
}
component_id = int_entry->component_id;
click_event = int_entry->click_event;
click_show = int_entry->click_show;
toolbox_event.hdr.flags = 0;
if (click_event) {
toolbox_event.hdr.size = sizeof(ToolboxEventHeader);
toolbox_event.hdr.event_code = click_event;
} else {
toolbox_event.hdr.size = sizeof(Menu_Selection_Event);
toolbox_event.hdr.event_code = Menu_Selection;
}
DEBUG debug_output ("e","Menu: event code is 0x%x\n", toolbox_event.hdr.event_code);
regs.r[0] = 0;
regs.r[1] = (int) object_id;
regs.r[2] = component_id;
regs.r[3] = (int) &toolbox_event;
if ((e = _kernel_swi (Toolbox_RaiseToolboxEvent, &regs, &regs)) != NULL) {
return e;
}
if (click_show) {
regs.r[0] = (int_entry->flags & MENU_INT_ENTRY_FLAGS_CLICK_SHOW_TRANSIENT) ? 1 : 0;
regs.r[1] = (int) click_show;
regs.r[2] = 0; /* Default screen location */
regs.r[3] = 0; /* NULL - this doesn't point at anything */
regs.r[4] = (int) object_id;
regs.r[5] = component_id;
if ((e = _kernel_swi (Toolbox_ShowObject, &regs, &regs)) != NULL) {
return e;
}
DEBUG debug_output ("click_show","Menu (click show): about to show %8x\n",click_show);
}
r->r[0] = 0;
id_block->self_id = object_id; /* not really necessary */
id_block->self_component = component_id;
IGNORE(t);
return NULL;
}
_kernel_oserror *event_menu_to_show (TaskDescriptor *t, IDBlock *id_block, _kernel_swi_regs *r) {
DEBUG debug_output ("e","Menu: global_menu.t = 0x%x; t = 0x%x\n",global_menu.t,t);
if (global_menu.t == t) { /* No further checking - assume this is it */
global_menu.flags |= GLOBAL_MENU_INFO_FLAGS_SHOW_NEXT;
/*
id_block->self_id = global_menu.current->hdr.object_id;
*/
DEBUG debug_output ("e","Menu: self id, 0x%x; menu int id, 0x%x\n", id_block->self_id, global_menu.current->hdr.object_id);
}
IGNORE(r);
IGNORE(id_block);
return NULL;
}
/* 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.
*/
/* Title: getstate.c
* Purpose: return state for a Menu Object
* Author: TGR
* History: 25-Apr-94: TGR: created
*
*/
#include <stdio.h>
#include <stdlib.h>
#include "kernel.h"
#include "swis.h"
#include "const.h"
#include "macros.h"
#include "services.h"
#include "debug.h"
#include "mem.h"
#include "messages.h"
#include "objects.toolbox.h"
#include "objects.menu.h"
#include "auxiliary.h"
#include "object.h"
#include "task.h"
#include "getstate.h"
extern _kernel_oserror *getstate_menu (_kernel_swi_regs *r, TaskDescriptor *t)
{
/*
* request for info about an object
* R0 = 5
* R1 = Object ID
* R2 = internal handle returned when Object was created
* R3 = wimp task handle of caller (use to identify task descriptor)
* R4 -> user regs R0-R9
* R0 = flags
* R1 = Object ID
*/
/*
* return state in R0
*
*/
ObjectID object_id = (ObjectID) r->r[1];
r->r[0] = ((global_menu.t == t) && (global_menu.top->hdr.object_id == object_id)) ?
Toolbox_GetObjectState_Showing : 0;
IGNORE(t);
return NULL;
}
/* 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.
*/
/* Title: hide.c
* Purpose: hide a Menu Object
* Author: TGR
* History: 4-Nov-93: TGR: created
*
*/
#include <stdio.h>
#include <stdlib.h>
#include "kernel.h"
#include "swis.h"
#include "const.h"
#include "macros.h"
#include "objects.toolbox.h"
#include "objects.menu.h"
#include "string32.h"
#include "messages.h"
#include "services.h"
#include "debug.h"
#include "mem.h"
#include "auxiliary.h"
#include "Menu.h"
#include "object.h"
#include "task.h"
#include "hide.h"
extern _kernel_oserror *hide_menu (_kernel_swi_regs *r, TaskDescriptor *t)
{
/*
* request to hide an object
* R0 = 4
* R1 = Object ID
* R2 = internal handle returned when Object was created
* R3 = wimp task handle of caller (use to identify task descriptor)
* R4 -> user regs R0-R9
* R0 = flags
* R1 = Object ID
*
*/
/*
* Remove the object from view.
*/
_kernel_oserror *e;
_kernel_swi_regs regs;
ObjectID object_id = (ObjectID) r->r[1];
if ((global_menu.t == t) && (global_menu.top->hdr.object_id == object_id)) {
DEBUG debug_output ("h","Menu: hiding menus\n");
regs.r[1] = -1;
if ((e = _kernel_swi (Wimp_CreateMenu, &regs, &regs)) != NULL)
return e;
return has_been_hidden ();
}
return NULL;
}
This diff is collapsed.
/* 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.
*/
/* Title: show.c
* Purpose: show a Menu Object
* Author: TGR
* History: 4-Nov-93: TGR: created
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "kernel.h"
#include "swis.h"
#include "const.h"
#include "macros.h"
#include "string32.h"
#include "messages.h"
#include "objects.toolbox.h"
#include "objects.menu.h"
#include "services.h"
#include "debug.h"
#include "mem.h"
#include "Menu.h"
#include "object.h"
#include "auxiliary.h"
#include "task.h"
#include "show.h"
_kernel_oserror *show_menu_coords (_kernel_swi_regs *user_regs,DisplayInfo *menu_coords);
extern _kernel_oserror *show_menu (_kernel_swi_regs *r, TaskDescriptor *t)
{
/*
* request to show an object
* R0 = 3
* R1 = Object ID
* R2 = internal handle returned when Object was created
* R3 = wimp task handle of caller (use to identify task descriptor)
* R4 -> user regs R0-R9
* R0 = flags
* R1 = Object ID
* R2 = type of show
* R3 -> buffer giving Object-specific data for showing this
* Object
* R4 = Parent Object ID
* R5 = Parent Component ID
*/
/*
* Function to "display" an Object on the screen. If R2 == -1, then
* display in 64 OS units left of pointer. If R2 == -2, then display
* 96 OS units from bottom of icon bar.
* If Object has bit set to say warn before show, then we should just
* send Toolbox Event, and wait for the next call to Wimp_Poll after
* the event is delivered before the Object is actually shown
* (ie catch it in the prefilter).
*
*/
_kernel_swi_regs regs,
*user_regs = (_kernel_swi_regs *) r->r[4];
_kernel_oserror *e;
MenuInternal *menu_int = (MenuInternal *) r->r[2];
ObjectID object_id = menu_int->hdr.object_id;
ToolboxEvent toolbox_event;
Menu_AboutToBeShown_Event
*menu_atbs;
DisplayInfo menu_coords;
BOOL is_submenu = user_regs->r[0] & 2;
int count;
DEBUG debug_output ("s","Menu: entering show, task = 0x%x, menu_int=0x%x, object_id=0x%x\n",(int)t,menu_int,object_id);
DEBUG if (object_id != (ObjectID) user_regs->r[1] || user_regs->r[1] != r->r[1]) debug_output ("s","Menu: sanity check reveals object ids unequal\n");
if ((e = show_menu_coords (user_regs,&menu_coords)) != NULL)
return e;
global_menu.x = menu_coords.x;
global_menu.y = menu_coords.y;
global_menu.current = menu_int;
global_menu.t = t;
if (!is_submenu) {
global_menu.top = global_menu.current;
}
global_menu.flags &= ~GLOBAL_MENU_INFO_FLAGS_SHOW_NEXT;
r->r[0] = (int) global_menu.current->hdr.wimp_menu;
count = (menu_int->hdr.flags&MENU_INT_FLAGS_GENERATE_SHOW_EVENT)
? ((menu_int->hdr.show_event)
? 2
: 1)
: 0;
if (!count) {
global_menu.flags |= GLOBAL_MENU_INFO_FLAGS_IS_SHOWING;
return (is_submenu) ? menu_show_submenu_actual () : menu_show_actual ();
}
while (count--) {
if (count) {
DEBUG debug_output ("s","Menu: sending 0x%x as show_event\n",menu_int->hdr.show_event);
toolbox_event.hdr.event_code = menu_int->hdr.show_event;
} else {
DEBUG debug_output ("s","Menu: sending ordinary show_event\n",menu_int->hdr.show_event);
toolbox_event.hdr.event_code = Menu_AboutToBeShown;
}
/* Show warning flag */
regs.r[0] = 0; /* flags*/
regs.r[1] = r->r[1]; /* Object id */
regs.r[2] = -1; /* Component id */
regs.r[3] = (int) &toolbox_event;
toolbox_event.hdr.size = sizeof(Menu_AboutToBeShown_Event);
toolbox_event.hdr.flags = /*user_regs->r[0]*/0;
menu_atbs = (Menu_AboutToBeShown_Event *) &toolbox_event;
menu_atbs->show_type = user_regs->r[2];
menu_atbs->x = global_menu.x;
menu_atbs->y = global_menu.y;
if ((e = _kernel_swi (Toolbox_RaiseToolboxEvent, &regs, &regs)) != NULL)
return e;
}
return NULL;
}
_kernel_oserror *show_menu_coords (_kernel_swi_regs *user_regs,DisplayInfo *menu_coords) {
_kernel_oserror *e;
_kernel_swi_regs regs;
DisplayInfo *coords = (DisplayInfo *) user_regs->r[3];
wimp_PointerInfo ptr_info;
switch (user_regs->r[2]) {
case 1:
case 2:
menu_coords->x = coords->x;
menu_coords->y = coords->y;
break;
default:
regs.r[1] = (int) &ptr_info;
if ((e = _kernel_swi (Wimp_GetPointerInfo, &regs, &regs)) != NULL) return e;
menu_coords->x = ptr_info.x - 64;
menu_coords->y = ptr_info.y;
break;
}
DEBUG debug_output ("s","Menu: show coordinates are (%d,%d)\n",menu_coords->x,menu_coords->y);
return NULL;
}
/* 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.
*/
/* Title: task.c
* Purpose: task handling for the Menu module
* Author: TGR
* History: 16-Nov-93: TGR: created from IDJ template
*
*/
#include <stdio.h>
#include <stdlib.h>
#include "kernel.h"
#include "swis.h"
#include "const.h"
#include "macros.h"
#include "string32.h"
#include "messages.h"
#include "objects.toolbox.h"
#include "objects.menu.h"
#include "services.h"
#include "debug.h"
#include "mem.h"
#include "Menu.h"
#include "object.h"
#include "auxiliary.h"
#include "task.h"
/*
* This module has a linked list of client tasks.
* task_add gets called when a Service_ToolboxTaskBorn
* service call goes round.
* The task is removed when the Service_WimpCloseDown is
* received.
* Each task keeps an Object list
*/
static TaskDescriptor *task__list = NULL;
extern BOOL task_any_active(void)
{
return task__list != NULL;
}
extern TaskDescriptor *task_find (int task_handle)
{
/*
* Function to return a TaskDescriptor corresponding to
* a task with a given Wimp handle
*/
TaskDescriptor *t;
DEBUG debug_output ("t","Menu: looking for task 0x%x\n",task_handle);
t = task__list;
while (t != NULL)
{
if (t->task_handle == task_handle)
break;
t = t->next;
}
return t;
}
extern void task_remove (int task_handle)
{
/*
* Function to remove a task descriptor from the list, given its
* Wimp task handle. Memory is freed, and we also delete any objects
* owned by the exiting task.
*/
TaskDescriptor *t = task__list;
TaskDescriptor *prev_t = NULL, *next = NULL;
MenuInternal *i,*j;
int c;
DEBUG debug_output ("t","Menu: looking to delete task 0x%x\n",task_handle);
while (t != NULL)
{
next = t->next;
if (t->task_handle == task_handle)
{
/*
* remove this task's object's list
*/
if (t->object_list != NULL) {
i = t->object_list;
/* If something horrible goes wrong whilst we're clearing up,
then we'll just re-enter here and send ourselves into an
infinite loop, so remove the task from the list before hand. */
if (t == task__list)
task__list = next;
else
prev_t->next = next;
mem_freek (t);
do {
j = i->hdr.forward;
if (global_menu.top == i) {
global_menu.top = NULL;
global_menu.current = NULL;
global_menu.flags &= ~GLOBAL_MENU_INFO_FLAGS_IS_SHOWING
& ~GLOBAL_MENU_INFO_FLAGS_SHOW_NEXT;
global_menu.t = NULL;
}
if ((i->hdr.wimp_menu)->hdr.title.indirect_text.buffer)
mem_freek ((i->hdr.wimp_menu)->hdr.title.indirect_text.buffer);
/* may not be any help */
if (i->hdr.help_message) mem_freek (i->hdr.help_message);
for (c=0;c<i->hdr.num_entries;c++) {
remove_menu_entry (wimp_menu_entry(i->hdr.wimp_menu,c),menu_internal_entry(i,c));
}
if (i->hdr.entries) mem_freek (i->hdr.entries);
mem_freek (i->hdr.wimp_menu);
mem_freek (i);
} while ((i=j) != t->object_list);
}
/*
* remove the task descriptor itself
*/
else {
if (t == task__list)
task__list = next;
else
prev_t->next = next;
mem_freek (t);
}
return;
}
prev_t = t;
t = next;
}
}
extern void task_add (int task_handle)
{
/*
* Function to add a task descriptor to the list of active
* Toolbox tasks.
*/
/*
* extra safety check, we make sure that the task is not already there!
*/
TaskDescriptor *new_t;
DEBUG debug_output ("t","Menu: adding task\n");
if (task_find (task_handle) != NULL)
return;
/*
* add task to list
*/
if ((new_t = mem_alloc (sizeof(TaskDescriptor))) == NULL)
{
raise_toolbox_error(Menu_AllocFailed,0,0,-1);
return;
}
new_t->task_handle = task_handle;
new_t->next = task__list;
new_t->object_list = NULL;
task__list = new_t;
DEBUG debug_output ("t","Menu: added task's handle = 0x%x\n",task_handle);
}
; 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.
;
; Title: cmhg.toolbox
; Purpose: module header for a Menu Object module
; Author: TGR
; History: 1-Nov-93: TGR: version 1.00
; 6-Jun-94: NK: version 1.08
; 25-Jun-94: NK: version 1.10
; 6-Jul-94: TGR: version 0.12 (don't ask me, I only work here)
; PRODUCT RELEASE
; 06-Feb-95: IDJ: version 0.22
; fixes AQU-01203 (menu_set_entry_text bug) for Black ROM
;
initialisation-code: Menu_init
finalisation-code: Menu_finalise
service-call-handler: Menu_services 0x44ec1, 0x44ec2, 0x44ec3
title-string: Menu
help-string: Menu 0.23
command-keyword-table: Menu_commands
Menu_Memory()
swi-chunk-base-number: 0x828c0
swi-handler-code: Menu_SWI_handler
swi-decoding-table: Menu,
ClassSWI, PostFilter, PreFilter, UpdateTree
; 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.
;
; Title: cmhg.toolbox
; Purpose: module header for a Menu Object module
; Author: TGR
; History: 1-Nov-93: TGR: version 1.00
; 6-Jun-94: NK: version 1.08
; 25-Jun-94: NK: version 1.10
; 6-Jul-94: TGR: version 0.12 (don't ask me, I only work here)
; PRODUCT RELEASE
; 06-Feb-95: IDJ: version 0.22
; fixes AQU-01203 (menu_set_entry_text bug) for Black ROM
;
initialisation-code: Menu_init
finalisation-code: Menu_finalise
service-call-handler: Menu_services 0x44ec1, 0x44ec2, 0x44ec3
title-string: Menu
help-string: Menu 0.23
swi-chunk-base-number: 0x828c0
swi-handler-code: Menu_SWI_handler
swi-decoding-table: Menu,
ClassSWI, PostFilter, PreFilter, UpdateTree
/* 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.
*/
/* Title: Menu.h
* Purpose: main module of a Menu Object module
* Author: TGR
* History: 2-Nov-93: TGR: created from IDJ skeleton
*
*/
#ifndef __Menu_h
#define __Menu_h
extern _kernel_oserror *Menu_init(char *cmd_tail, int podule_base, void *pw);
extern _kernel_oserror *Menu_finalise (int fatal, int podule, void *pw);
extern void Menu_services(int service_number, _kernel_swi_regs *r, void *pw);
extern _kernel_oserror *Menu_SWI_handler(int swi_no, _kernel_swi_regs *r, void *pw);
#if debugging
extern _kernel_oserror *Menu_commands(char *arg_string, int argc, int cmd_no, void *pw);
#endif
#endif
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment