Version 1.6
This commit is contained in:
parent
1063d60252
commit
5f59b3d0da
|
@ -0,0 +1,101 @@
|
||||||
|
ToolsMenu - Add tools to the Workbench Tools menu
|
||||||
|
|
||||||
|
Copyright (C) 2015, 2018 Kim Fastrup Larsen
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation, either ver-
|
||||||
|
sion 3 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be use-
|
||||||
|
ful, but WITHOUT ANY WARRANTY; without even the implied war-
|
||||||
|
ranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
See the GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public Li-
|
||||||
|
cense along with this program. If not, see
|
||||||
|
<http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
The author can be contacted on <kimflarsen@hotmail.com>
|
||||||
|
|
||||||
|
|
||||||
|
New in version 1.6:
|
||||||
|
|
||||||
|
- Minor UI adjustments
|
||||||
|
- New, "proper" requester for About
|
||||||
|
- Modularized the source code
|
||||||
|
|
||||||
|
|
||||||
|
ToolsMenu is a commodity that will let you add tools to the Tools menu on
|
||||||
|
your Workbench screen. Once a tool has been added, you can run it by
|
||||||
|
selecting it from the menu. Any icons selected on the Workbench at that
|
||||||
|
moment become arguments for the tool.
|
||||||
|
|
||||||
|
For example, if you add MultiView, you can then select the icon of an image
|
||||||
|
on the Workbench, then select MultiView from the menu to view that image.
|
||||||
|
|
||||||
|
Tools will be run as if started by the Workbench. You will not be able to
|
||||||
|
run tools that do not have a proper tool icons.
|
||||||
|
|
||||||
|
Adding tools should be pretty self explanatory. Drag tool icons into the
|
||||||
|
window to add them, after which you can edit their names if you like. You
|
||||||
|
can also click the "New" button to manually enter a tool. You then write the
|
||||||
|
name of the tool (as you would like it to appear in the menu) under the
|
||||||
|
list, and type in the full path of the tool over on the right where it says
|
||||||
|
"Tool". The path must include the name of the tool's executable file.
|
||||||
|
|
||||||
|
When you are happy with your selection of tools, you must remember to save
|
||||||
|
them from the pull down menu. The definitions will be saved as tool types
|
||||||
|
in the commodity's icon.
|
||||||
|
|
||||||
|
ToolsMenu requires Kickstart 2 or later.
|
||||||
|
|
||||||
|
The source code is included in the hope that it will be useful to those out
|
||||||
|
there who still enjoy programming for the Amiga. Elements of interest
|
||||||
|
include:
|
||||||
|
|
||||||
|
- How to use Catcomp so a project can be localized easily
|
||||||
|
- How to implement a commodity sporting a GUI
|
||||||
|
- How to implement a dynamic GUI using Gadtools
|
||||||
|
- How to read and write tool types
|
||||||
|
- How to support dragging icons into a window
|
||||||
|
- How to add items to the Workbench Tools menu
|
||||||
|
- How to load and run other programs as DOS processes
|
||||||
|
- How to pretend to be Workbench
|
||||||
|
|
||||||
|
|
||||||
|
History:
|
||||||
|
|
||||||
|
1.6 (Nov 26, 2018)
|
||||||
|
|
||||||
|
- Minor UI adjustments
|
||||||
|
- New, "proper" requester for About
|
||||||
|
- Modularized the source code
|
||||||
|
|
||||||
|
1.5 (Jul 28, 2015)
|
||||||
|
|
||||||
|
- Busy pointer for Kickstart 2
|
||||||
|
- Optimized and cleaned up a few things, made code more portable
|
||||||
|
|
||||||
|
1.4 (Apr 22, 2015)
|
||||||
|
|
||||||
|
- Improved layout for big fonts.
|
||||||
|
- Added "About..."
|
||||||
|
|
||||||
|
1.3 (Feb 12, 2015)
|
||||||
|
|
||||||
|
- Fixed an issue that caused some commodities (and possibly other tools) to
|
||||||
|
crash.
|
||||||
|
|
||||||
|
1.2 (Feb 3, 2015)
|
||||||
|
|
||||||
|
- Use the user's preferred screen font.
|
||||||
|
|
||||||
|
1.1 (Jan 19, 2015)
|
||||||
|
|
||||||
|
- Fixed an issue where trying to run a tool with an empty path would cause
|
||||||
|
a Guru Meditation.
|
||||||
|
|
||||||
|
1.0 (Jan 12, 2015)
|
||||||
|
|
||||||
|
- Initial release
|
Binary file not shown.
|
@ -0,0 +1,12 @@
|
||||||
|
PARAMETERS=REGISTERS
|
||||||
|
ANSI
|
||||||
|
SHORTINTEGERS
|
||||||
|
NOSTACKCHECK
|
||||||
|
STRINGMERGE
|
||||||
|
ERRORREXX
|
||||||
|
OPTIMIZE
|
||||||
|
OPTIMIZERINLINELOCAL
|
||||||
|
NOVERSION
|
||||||
|
MEMORYSIZE=HUGE
|
||||||
|
DEFINE USE_PRAGMAS
|
||||||
|
IGNORE=306
|
|
@ -0,0 +1,96 @@
|
||||||
|
/*
|
||||||
|
ToolsMenu - Add tools to the Workbench Tools menu
|
||||||
|
|
||||||
|
Copyright (C) 2015, 2018 Kim Fastrup Larsen
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation, either ver-
|
||||||
|
sion 3 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be use-
|
||||||
|
ful, but WITHOUT ANY WARRANTY; without even the implied war-
|
||||||
|
ranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
See the GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public Li-
|
||||||
|
cense along with this program. If not, see
|
||||||
|
<http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
The author can be contacted on <kimflarsen@hotmail.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <dos/dos.h>
|
||||||
|
#include <dos/rdargs.h>
|
||||||
|
#include <workbench/startup.h>
|
||||||
|
|
||||||
|
#include <clib/alib_protos.h>
|
||||||
|
#include <clib/dos_protos.h>
|
||||||
|
#include <clib/exec_protos.h>
|
||||||
|
|
||||||
|
#ifdef USE_PRAGMAS
|
||||||
|
#include <proto/dos.h>
|
||||||
|
#include <proto/exec.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "args.h"
|
||||||
|
|
||||||
|
#define DEF_CX_PRIORITY 0
|
||||||
|
#define DEF_CX_POPUP YES
|
||||||
|
#define DEF_CX_POPKEY "control alt t"
|
||||||
|
|
||||||
|
Args args;
|
||||||
|
|
||||||
|
static UBYTE **tool_types;
|
||||||
|
static struct RDArgs *rdargs;
|
||||||
|
|
||||||
|
static void get_wb_args(char **argv)
|
||||||
|
{
|
||||||
|
struct WBArg *wb_arg = ((struct WBStartup *) argv)->sm_ArgList;
|
||||||
|
|
||||||
|
args.exe.dir = wb_arg->wa_Lock;
|
||||||
|
args.exe.filename = wb_arg->wa_Name;
|
||||||
|
if ((tool_types = ArgArrayInit(0, argv)) == NULL)
|
||||||
|
exit(RETURN_FAIL);
|
||||||
|
args.cx_priority = ArgInt(tool_types, "CX_PRIORITY", DEF_CX_PRIORITY);
|
||||||
|
args.cx_popup = strcmp(ArgString(tool_types, "CX_POPUP", DEF_CX_POPUP ?
|
||||||
|
"YES" : "NO"), "NO") != 0;
|
||||||
|
args.cx_popkey = ArgString(tool_types, "CX_POPKEY", DEF_CX_POPKEY);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void get_shell_args(char **argv)
|
||||||
|
{
|
||||||
|
LONG sh_args[3];
|
||||||
|
|
||||||
|
args.exe.dir = ((struct Process *) FindTask(NULL))->pr_CurrentDir;
|
||||||
|
args.exe.filename = argv[0];
|
||||||
|
sh_args[0] = DEF_CX_PRIORITY;
|
||||||
|
sh_args[1] = (LONG) DEF_CX_POPKEY;
|
||||||
|
sh_args[2] = DEF_CX_POPUP ? (LONG) "YES" : (LONG) "NO";
|
||||||
|
if ((rdargs = ReadArgs(TEMPLATE, sh_args, NULL)) == NULL) {
|
||||||
|
PrintFault(IoErr(), argv[0]);
|
||||||
|
exit(RETURN_ERROR);
|
||||||
|
}
|
||||||
|
args.cx_priority = sh_args[0];
|
||||||
|
args.cx_popkey = (STRPTR) sh_args[1];
|
||||||
|
args.cx_popup = strcmp((char *) sh_args[2], "YES") == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void args_set_up(int argc, char **argv)
|
||||||
|
{
|
||||||
|
if (argc == 0)
|
||||||
|
get_wb_args(argv);
|
||||||
|
else
|
||||||
|
get_shell_args(argv);
|
||||||
|
}
|
||||||
|
|
||||||
|
void args_clean_up()
|
||||||
|
{
|
||||||
|
if (rdargs != NULL)
|
||||||
|
FreeArgs(rdargs);
|
||||||
|
if (tool_types != NULL)
|
||||||
|
ArgArrayDone();
|
||||||
|
}
|
|
@ -0,0 +1,46 @@
|
||||||
|
/*
|
||||||
|
ToolsMenu - Add tools to the Workbench Tools menu
|
||||||
|
|
||||||
|
Copyright (C) 2015, 2018 Kim Fastrup Larsen
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation, either ver-
|
||||||
|
sion 3 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be use-
|
||||||
|
ful, but WITHOUT ANY WARRANTY; without even the implied war-
|
||||||
|
ranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
See the GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public Li-
|
||||||
|
cense along with this program. If not, see
|
||||||
|
<http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
The author can be contacted on <kimflarsen@hotmail.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef ARGS_H
|
||||||
|
#define ARGS_H
|
||||||
|
|
||||||
|
#include <dos/dos.h>
|
||||||
|
#include <exec/types.h>
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
struct {
|
||||||
|
BPTR dir;
|
||||||
|
char *filename;
|
||||||
|
} exe;
|
||||||
|
BYTE cx_priority;
|
||||||
|
Bool cx_popup;
|
||||||
|
STRPTR cx_popkey;
|
||||||
|
} Args;
|
||||||
|
|
||||||
|
extern Args args;
|
||||||
|
|
||||||
|
void args_set_up(int argc, char **argv);
|
||||||
|
void args_clean_up(void);
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,135 @@
|
||||||
|
/*
|
||||||
|
ToolsMenu - Add tools to the Workbench Tools menu
|
||||||
|
|
||||||
|
Copyright (C) 2015, 2018 Kim Fastrup Larsen
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation, either ver-
|
||||||
|
sion 3 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be use-
|
||||||
|
ful, but WITHOUT ANY WARRANTY; without even the implied war-
|
||||||
|
ranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
See the GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public Li-
|
||||||
|
cense along with this program. If not, see
|
||||||
|
<http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
The author can be contacted on <kimflarsen@hotmail.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <dos/dos.h>
|
||||||
|
#include <libraries/commodities.h>
|
||||||
|
|
||||||
|
#include <clib/commodities_protos.h>
|
||||||
|
#include <clib/exec_protos.h>
|
||||||
|
|
||||||
|
#ifdef USE_PRAGMAS
|
||||||
|
#include <proto/commodities.h>
|
||||||
|
#include <proto/exec.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <strings.h>
|
||||||
|
|
||||||
|
#define CATCOMP_NUMBERS
|
||||||
|
|
||||||
|
#include "args.h"
|
||||||
|
#include "broker.h"
|
||||||
|
#include "catalog.h"
|
||||||
|
#include "common.h"
|
||||||
|
#include "cx.h"
|
||||||
|
#include "error.h"
|
||||||
|
#include "strings.h"
|
||||||
|
|
||||||
|
static struct MsgPort *broker_port;
|
||||||
|
static CxObj *broker;
|
||||||
|
|
||||||
|
ULONG broker_set_up()
|
||||||
|
{
|
||||||
|
struct NewBroker new_broker;
|
||||||
|
LONG error;
|
||||||
|
CxObj *filter;
|
||||||
|
|
||||||
|
if ((broker_port = CreateMsgPort()) == NULL)
|
||||||
|
exit(RETURN_FAIL);
|
||||||
|
memset(&new_broker, 0, sizeof new_broker);
|
||||||
|
new_broker.nb_Version = NB_VERSION;
|
||||||
|
new_broker.nb_Name = APP_NAME;
|
||||||
|
new_broker.nb_Title = TITLE;
|
||||||
|
new_broker.nb_Descr = get_string(MSG_DESCRIPTION);
|
||||||
|
new_broker.nb_Unique = NBU_UNIQUE | NBU_NOTIFY;
|
||||||
|
new_broker.nb_Flags = COF_SHOW_HIDE;
|
||||||
|
new_broker.nb_Pri = args.cx_priority;
|
||||||
|
new_broker.nb_Port = broker_port;
|
||||||
|
if ((broker = CxBroker(&new_broker, &error)) == NULL)
|
||||||
|
exit((error == CBERR_DUP) ? RETURN_OK : RETURN_FAIL);
|
||||||
|
if ((filter = CxFilter(args.cx_popkey)) == NULL)
|
||||||
|
exit(RETURN_FAIL);
|
||||||
|
AttachCxObj(broker, filter);
|
||||||
|
AttachCxObj(filter, CxSender(broker_port, 0));
|
||||||
|
AttachCxObj(filter, CxTranslate(NULL));
|
||||||
|
if ((error = CxObjError(filter)) != 0) {
|
||||||
|
if (error == COERR_BADFILTER) {
|
||||||
|
error_message(get_string(MSG_ERR_HOTKEY), NULL);
|
||||||
|
exit(RETURN_ERROR);
|
||||||
|
} else
|
||||||
|
exit(RETURN_FAIL);
|
||||||
|
}
|
||||||
|
ActivateCxObj(broker, 1);
|
||||||
|
return 1UL << broker_port->mp_SigBit;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void handle_command(ULONG msg_id)
|
||||||
|
{
|
||||||
|
switch (msg_id) {
|
||||||
|
case CXCMD_DISABLE:
|
||||||
|
ActivateCxObj(broker, 0);
|
||||||
|
cx_disable();
|
||||||
|
break;
|
||||||
|
case CXCMD_ENABLE:
|
||||||
|
ActivateCxObj(broker, 1);
|
||||||
|
cx_enable();
|
||||||
|
break;
|
||||||
|
case CXCMD_KILL:
|
||||||
|
cx_quit();
|
||||||
|
break;
|
||||||
|
case CXCMD_UNIQUE:
|
||||||
|
case CXCMD_APPEAR:
|
||||||
|
cx_show();
|
||||||
|
break;
|
||||||
|
case CXCMD_DISAPPEAR:
|
||||||
|
cx_hide();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void broker_handle_signal()
|
||||||
|
{
|
||||||
|
CxMsg *msg;
|
||||||
|
ULONG msg_type, msg_id;
|
||||||
|
|
||||||
|
while ((msg = (CxMsg *) GetMsg(broker_port)) != NULL) {
|
||||||
|
msg_type = CxMsgType(msg);
|
||||||
|
msg_id = CxMsgID(msg);
|
||||||
|
ReplyMsg((struct Message *) msg);
|
||||||
|
switch (msg_type) {
|
||||||
|
case CXM_IEVENT:
|
||||||
|
/* Must be Hot Key event */
|
||||||
|
cx_show();
|
||||||
|
break;
|
||||||
|
case CXM_COMMAND:
|
||||||
|
handle_command(msg_id);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void broker_clean_up()
|
||||||
|
{
|
||||||
|
if (broker != NULL)
|
||||||
|
DeleteCxObjAll(broker);
|
||||||
|
delete_port(broker_port);
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
/*
|
||||||
|
ToolsMenu - Add tools to the Workbench Tools menu
|
||||||
|
|
||||||
|
Copyright (C) 2015, 2018 Kim Fastrup Larsen
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation, either ver-
|
||||||
|
sion 3 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be use-
|
||||||
|
ful, but WITHOUT ANY WARRANTY; without even the implied war-
|
||||||
|
ranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
See the GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public Li-
|
||||||
|
cense along with this program. If not, see
|
||||||
|
<http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
The author can be contacted on <kimflarsen@hotmail.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef BROKER_H
|
||||||
|
#define BROKER_H
|
||||||
|
|
||||||
|
#include <exec/types.h>
|
||||||
|
|
||||||
|
ULONG broker_set_up(void);
|
||||||
|
void broker_handle_signal(void);
|
||||||
|
void broker_clean_up(void);
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,67 @@
|
||||||
|
/*
|
||||||
|
ToolsMenu - Add tools to the Workbench Tools menu
|
||||||
|
|
||||||
|
Copyright (C) 2015, 2018 Kim Fastrup Larsen
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation, either ver-
|
||||||
|
sion 3 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be use-
|
||||||
|
ful, but WITHOUT ANY WARRANTY; without even the implied war-
|
||||||
|
ranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
See the GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public Li-
|
||||||
|
cense along with this program. If not, see
|
||||||
|
<http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
The author can be contacted on <kimflarsen@hotmail.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <exec/types.h>
|
||||||
|
|
||||||
|
#include <clib/locale_protos.h>
|
||||||
|
|
||||||
|
#ifdef USE_PRAGMAS
|
||||||
|
#include <proto/locale.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "catalog.h"
|
||||||
|
|
||||||
|
#define CATCOMP_BLOCK
|
||||||
|
#include "strings.h"
|
||||||
|
|
||||||
|
extern struct Library *LocaleBase;
|
||||||
|
|
||||||
|
static APTR catalog;
|
||||||
|
|
||||||
|
void open_catalog(STRPTR name)
|
||||||
|
{
|
||||||
|
if (LocaleBase != NULL)
|
||||||
|
catalog = OpenCatalog(NULL, name, TAG_DONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
STRPTR get_string(ULONG id)
|
||||||
|
{
|
||||||
|
LONG *l;
|
||||||
|
UWORD *w;
|
||||||
|
STRPTR built_in;
|
||||||
|
|
||||||
|
l = (LONG *) CatCompBlock;
|
||||||
|
while (*l != id) {
|
||||||
|
w = (UWORD *) ((ULONG) l + 4);
|
||||||
|
l = (LONG *) ((ULONG) l + (ULONG) *w + 6);
|
||||||
|
}
|
||||||
|
built_in = (STRPTR) ((ULONG) l + 6);
|
||||||
|
return (catalog != NULL) ? GetCatalogStr(catalog,id,built_in) : built_in;
|
||||||
|
}
|
||||||
|
|
||||||
|
void close_catalog()
|
||||||
|
{
|
||||||
|
if (LocaleBase != NULL) {
|
||||||
|
CloseCatalog(catalog);
|
||||||
|
catalog = NULL;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
/*
|
||||||
|
ToolsMenu - Add tools to the Workbench Tools menu
|
||||||
|
|
||||||
|
Copyright (C) 2015, 2018 Kim Fastrup Larsen
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation, either ver-
|
||||||
|
sion 3 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be use-
|
||||||
|
ful, but WITHOUT ANY WARRANTY; without even the implied war-
|
||||||
|
ranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
See the GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public Li-
|
||||||
|
cense along with this program. If not, see
|
||||||
|
<http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
The author can be contacted on <kimflarsen@hotmail.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef CATALOG_H
|
||||||
|
#define CATALOG_H
|
||||||
|
|
||||||
|
#include <exec/types.h>
|
||||||
|
|
||||||
|
void open_catalog(STRPTR catalog);
|
||||||
|
STRPTR get_string(ULONG id);
|
||||||
|
void close_catalog(void);
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,95 @@
|
||||||
|
/*
|
||||||
|
ToolsMenu - Add tools to the Workbench Tools menu
|
||||||
|
|
||||||
|
Copyright (C) 2015, 2018 Kim Fastrup Larsen
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation, either ver-
|
||||||
|
sion 3 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be use-
|
||||||
|
ful, but WITHOUT ANY WARRANTY; without even the implied war-
|
||||||
|
ranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
See the GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public Li-
|
||||||
|
cense along with this program. If not, see
|
||||||
|
<http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
The author can be contacted on <kimflarsen@hotmail.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <exec/lists.h>
|
||||||
|
#include <exec/memory.h>
|
||||||
|
|
||||||
|
#include <clib/exec_protos.h>
|
||||||
|
|
||||||
|
#ifdef USE_PRAGMAS
|
||||||
|
#include <proto/exec.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
|
char *copy_of(char *s)
|
||||||
|
{
|
||||||
|
char *result;
|
||||||
|
|
||||||
|
if ((result = AllocVec(strlen(s) + 1, MEMF_PUBLIC)) != NULL)
|
||||||
|
strcpy(result, s);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void for_all(struct List *l, void (*f)(void *))
|
||||||
|
{
|
||||||
|
struct Node *n, *next;
|
||||||
|
|
||||||
|
/* This form of iteration allows f() to free nodes */
|
||||||
|
for (n = l->lh_Head; (next = n->ln_Succ) != NULL; n = next)
|
||||||
|
(*f)(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
Bool is_in_list(struct List *l, struct Node *node)
|
||||||
|
{
|
||||||
|
struct Node *n;
|
||||||
|
|
||||||
|
for (n = l->lh_Head; n->ln_Succ != NULL; n = n->ln_Succ)
|
||||||
|
if (n == node)
|
||||||
|
return YES;
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Node *node_at(struct List *l, int i)
|
||||||
|
{
|
||||||
|
struct Node *n;
|
||||||
|
|
||||||
|
for (n = l->lh_Head; n->ln_Succ != NULL; n = n->ln_Succ) {
|
||||||
|
if (i == 0)
|
||||||
|
return n;
|
||||||
|
--i;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int length_of(struct List *l)
|
||||||
|
{
|
||||||
|
struct Node *n;
|
||||||
|
int result = 0;
|
||||||
|
|
||||||
|
for (n = l->lh_Head; n->ln_Succ != NULL; n = n->ln_Succ)
|
||||||
|
++result;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void delete_port(struct MsgPort *port)
|
||||||
|
{
|
||||||
|
struct Message *msg;
|
||||||
|
|
||||||
|
if (port != NULL) {
|
||||||
|
while ((msg = GetMsg(port)) != NULL)
|
||||||
|
ReplyMsg(msg);
|
||||||
|
DeleteMsgPort(port);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,45 @@
|
||||||
|
/*
|
||||||
|
ToolsMenu - Add tools to the Workbench Tools menu
|
||||||
|
|
||||||
|
Copyright (C) 2015, 2018 Kim Fastrup Larsen
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation, either ver-
|
||||||
|
sion 3 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be use-
|
||||||
|
ful, but WITHOUT ANY WARRANTY; without even the implied war-
|
||||||
|
ranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
See the GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public Li-
|
||||||
|
cense along with this program. If not, see
|
||||||
|
<http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
The author can be contacted on <kimflarsen@hotmail.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef COMMON_H
|
||||||
|
#define COMMON_H
|
||||||
|
|
||||||
|
#define APP_NAME "ToolsMenu"
|
||||||
|
#define VERSION "1.6"
|
||||||
|
#define DATE "26.11.2018"
|
||||||
|
#define COPYRIGHT "Copyright © 2015, 2018 Kim Fastrup Larsen"
|
||||||
|
#define TEMPLATE "CX_PRIORITY/N/K,CX_POPKEY/K,CX_POPUP/K"
|
||||||
|
#define CATALOG "toolsmenu.catalog"
|
||||||
|
#define TITLE APP_NAME " " VERSION
|
||||||
|
|
||||||
|
#define MAX_PATH_LENGTH 127
|
||||||
|
|
||||||
|
typedef enum { NO, YES } Bool;
|
||||||
|
|
||||||
|
char *copy_of(char *s);
|
||||||
|
void for_all(struct List *, void (*)(void *));
|
||||||
|
Bool is_in_list(struct List *, struct Node *);
|
||||||
|
struct Node *node_at(struct List *, int index);
|
||||||
|
int length_of(struct List *);
|
||||||
|
void delete_port(struct MsgPort *);
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,28 @@
|
||||||
|
/*
|
||||||
|
ToolsMenu - Add tools to the Workbench Tools menu
|
||||||
|
|
||||||
|
Copyright (C) 2015, 2018 Kim Fastrup Larsen
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation, either ver-
|
||||||
|
sion 3 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be use-
|
||||||
|
ful, but WITHOUT ANY WARRANTY; without even the implied war-
|
||||||
|
ranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
See the GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public Li-
|
||||||
|
cense along with this program. If not, see
|
||||||
|
<http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
The author can be contacted on <kimflarsen@hotmail.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef COMPILER_H
|
||||||
|
#define COMPILER_H
|
||||||
|
|
||||||
|
#define CHIP __chip
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,213 @@
|
||||||
|
/*
|
||||||
|
ToolsMenu - Add tools to the Workbench Tools menu
|
||||||
|
|
||||||
|
Copyright (C) 2015, 2018 Kim Fastrup Larsen
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation, either ver-
|
||||||
|
sion 3 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be use-
|
||||||
|
ful, but WITHOUT ANY WARRANTY; without even the implied war-
|
||||||
|
ranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
See the GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public Li-
|
||||||
|
cense along with this program. If not, see
|
||||||
|
<http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
The author can be contacted on <kimflarsen@hotmail.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <dos/dos.h>
|
||||||
|
#include <exec/memory.h>
|
||||||
|
|
||||||
|
#include <clib/alib_protos.h>
|
||||||
|
#include <clib/exec_protos.h>
|
||||||
|
|
||||||
|
#ifdef USE_PRAGMAS
|
||||||
|
#include <proto/exec.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#define CATCOMP_NUMBERS
|
||||||
|
|
||||||
|
#include "args.h"
|
||||||
|
#include "catalog.h"
|
||||||
|
#include "common.h"
|
||||||
|
#include "cx.h"
|
||||||
|
#include "gui.h"
|
||||||
|
#include "io.h"
|
||||||
|
#include "strings.h"
|
||||||
|
#include "wb.h"
|
||||||
|
|
||||||
|
struct List *tools;
|
||||||
|
|
||||||
|
static Bool enabled = YES;
|
||||||
|
|
||||||
|
static void free_tool(Tool *tool)
|
||||||
|
{
|
||||||
|
FreeVec(tool->node.ln_Name);
|
||||||
|
FreeVec(tool->path);
|
||||||
|
FreeMem(tool, sizeof *tool);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Tool *create_tool(char *name, char *path)
|
||||||
|
{
|
||||||
|
Tool *t;
|
||||||
|
|
||||||
|
if ((t = AllocMem(sizeof *t, MEMF_PUBLIC | MEMF_CLEAR)) == NULL)
|
||||||
|
return NULL;
|
||||||
|
if ((t->node.ln_Name = copy_of(name)) == NULL)
|
||||||
|
goto create_tool_failed;
|
||||||
|
if ((t->path = copy_of(path)) == NULL)
|
||||||
|
goto create_tool_failed;
|
||||||
|
return t;
|
||||||
|
|
||||||
|
create_tool_failed:
|
||||||
|
free_tool(t);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Tool *add_tool(char *name, char *path, struct Node *pred)
|
||||||
|
{
|
||||||
|
Tool *tool;
|
||||||
|
|
||||||
|
if ((tool = create_tool(name, path)) != NULL) {
|
||||||
|
Insert(tools, &tool->node, pred);
|
||||||
|
if (enabled)
|
||||||
|
wb_add_tool(tool);
|
||||||
|
}
|
||||||
|
return tool;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void remove_tool(Tool *tool)
|
||||||
|
{
|
||||||
|
if (enabled)
|
||||||
|
wb_remove_tool(tool);
|
||||||
|
Remove(&tool->node);
|
||||||
|
free_tool(tool);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Tool *do_update(Tool *(*f)(Tool *, char *, char *), Tool *tool,
|
||||||
|
char *name, char *path)
|
||||||
|
{
|
||||||
|
Tool *result;
|
||||||
|
|
||||||
|
gui_begin_update();
|
||||||
|
result = (*f)(tool, name, path);
|
||||||
|
gui_end_update();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Tool *append(Tool *unused, char *name, char *path)
|
||||||
|
{
|
||||||
|
return add_tool(name, path, tools->lh_TailPred);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Actually creates a new tool and then deletes the old one, to simplify low
|
||||||
|
memory failure scenarios. If name is blank, it will simply delete the
|
||||||
|
tool. */
|
||||||
|
static Tool *modify(Tool *tool, char *name, char *path)
|
||||||
|
{
|
||||||
|
Tool *new_tool = NULL;
|
||||||
|
|
||||||
|
if (*name != 0 && (new_tool = add_tool(name, path, &tool->node)) == NULL)
|
||||||
|
return tool;
|
||||||
|
remove_tool(tool);
|
||||||
|
return new_tool;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void add_to_menu(void *tool)
|
||||||
|
{
|
||||||
|
wb_add_tool((Tool *) tool);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void remove_from_menu(void *tool)
|
||||||
|
{
|
||||||
|
wb_remove_tool((Tool *) tool);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cx_set_up()
|
||||||
|
{
|
||||||
|
if ((tools = AllocMem(sizeof *tools, MEMF_PUBLIC)) == NULL)
|
||||||
|
exit(RETURN_FAIL);
|
||||||
|
NewList(tools);
|
||||||
|
io_read_definitions(args.exe.dir, args.exe.filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
Tool *cx_add_tool(char *name, char *path)
|
||||||
|
{
|
||||||
|
Tool *tool = do_update(append, NULL, name, path);
|
||||||
|
|
||||||
|
gui_edit(tool);
|
||||||
|
return tool;
|
||||||
|
}
|
||||||
|
|
||||||
|
Tool *cx_modify_tool(Tool *tool, char *name, char *path)
|
||||||
|
{
|
||||||
|
return do_update(modify, tool, name, path);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cx_enable()
|
||||||
|
{
|
||||||
|
if (!enabled) {
|
||||||
|
enabled = YES;
|
||||||
|
for_all(tools, add_to_menu);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void cx_disable()
|
||||||
|
{
|
||||||
|
if (enabled) {
|
||||||
|
enabled = NO;
|
||||||
|
for_all(tools, remove_from_menu);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void cx_show()
|
||||||
|
{
|
||||||
|
gui_show();
|
||||||
|
}
|
||||||
|
|
||||||
|
void cx_hide()
|
||||||
|
{
|
||||||
|
gui_hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
void cx_save_tools()
|
||||||
|
{
|
||||||
|
gui_begin_busy();
|
||||||
|
io_write_definitions(args.exe.dir, args.exe.filename);
|
||||||
|
gui_end_busy();
|
||||||
|
}
|
||||||
|
|
||||||
|
void cx_about()
|
||||||
|
{
|
||||||
|
gui_message(get_string(MSG_GAD_CONTINUE),
|
||||||
|
TITLE,
|
||||||
|
COPYRIGHT,
|
||||||
|
"",
|
||||||
|
"This program comes with ABSOLUTELY NO WARRANTY.",
|
||||||
|
"This is free software under the terms of",
|
||||||
|
"version 3 of the GNU General Public License.",
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cx_quit()
|
||||||
|
{
|
||||||
|
cx_hide();
|
||||||
|
cx_disable();
|
||||||
|
exit(RETURN_OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cx_clean_up()
|
||||||
|
{
|
||||||
|
if (tools != NULL) {
|
||||||
|
for_all(tools, free_tool);
|
||||||
|
FreeMem(tools, sizeof *tools);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,51 @@
|
||||||
|
/*
|
||||||
|
ToolsMenu - Add tools to the Workbench Tools menu
|
||||||
|
|
||||||
|
Copyright (C) 2015, 2018 Kim Fastrup Larsen
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation, either ver-
|
||||||
|
sion 3 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be use-
|
||||||
|
ful, but WITHOUT ANY WARRANTY; without even the implied war-
|
||||||
|
ranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
See the GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public Li-
|
||||||
|
cense along with this program. If not, see
|
||||||
|
<http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
The author can be contacted on <kimflarsen@hotmail.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef CX_H
|
||||||
|
#define CX_H
|
||||||
|
|
||||||
|
#include <exec/lists.h>
|
||||||
|
|
||||||
|
/* We will maintain a list of Tools as the main global state of this
|
||||||
|
commodity. The name of each Tool (ie. menu item) will be stored in
|
||||||
|
node.ln_Name. */
|
||||||
|
typedef struct {
|
||||||
|
struct Node node;
|
||||||
|
char *path;
|
||||||
|
struct AppMenuItem *menu_item;
|
||||||
|
} Tool;
|
||||||
|
|
||||||
|
extern struct List *tools;
|
||||||
|
|
||||||
|
void cx_set_up(void);
|
||||||
|
Tool *cx_add_tool(char *name, char *path);
|
||||||
|
Tool *cx_modify_tool(Tool *, char *name, char *path);
|
||||||
|
void cx_enable(void);
|
||||||
|
void cx_disable(void);
|
||||||
|
void cx_show(void);
|
||||||
|
void cx_hide(void);
|
||||||
|
void cx_save_tools(void);
|
||||||
|
void cx_about(void);
|
||||||
|
void cx_quit(void);
|
||||||
|
void cx_clean_up(void);
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,72 @@
|
||||||
|
## version $VER: toolsmenu.catalog 1.6 (26.11.2018)
|
||||||
|
## codeset 0
|
||||||
|
## language dansk
|
||||||
|
;
|
||||||
|
MSG_ERR_OPEN
|
||||||
|
Kunne ikke åbne %s
|
||||||
|
; Could not open %s
|
||||||
|
;
|
||||||
|
MSG_ERR_HOTKEY
|
||||||
|
Ugyldig genvejstast
|
||||||
|
; Illegal hot key
|
||||||
|
;
|
||||||
|
MSG_WINDOW_TITLE
|
||||||
|
%s: Tryk <%s>
|
||||||
|
; %s: Hot Key = <%s>
|
||||||
|
;
|
||||||
|
MSG_DESCRIPTION
|
||||||
|
Tilføj værktøjer til Workbench-menuen
|
||||||
|
; Add tools to the Workbench Tools Menu
|
||||||
|
;
|
||||||
|
MSG_PROJECT_MENU
|
||||||
|
Projekt
|
||||||
|
; Project
|
||||||
|
;
|
||||||
|
MSG_PROJECT_SAVE
|
||||||
|
Gemme menuposter
|
||||||
|
; Save Menu Items
|
||||||
|
;
|
||||||
|
MSG_PROJECT_HIDE
|
||||||
|
Gemme væk
|
||||||
|
; Hide
|
||||||
|
;
|
||||||
|
MSG_PROJECT_ABOUT
|
||||||
|
Omkring...
|
||||||
|
; About...
|
||||||
|
;
|
||||||
|
MSG_PROJECT_QUIT
|
||||||
|
Afbryde
|
||||||
|
; Quit
|
||||||
|
;
|
||||||
|
MSG_GAD_CONTINUE
|
||||||
|
Fortsætte
|
||||||
|
; Continue
|
||||||
|
;
|
||||||
|
MSG_GAD_MENU_ITEMS
|
||||||
|
Menuposter
|
||||||
|
; Menu Items
|
||||||
|
;
|
||||||
|
MSG_GAD_NEW
|
||||||
|
Ny
|
||||||
|
; New
|
||||||
|
;
|
||||||
|
MSG_GAD_DELETE
|
||||||
|
Slette
|
||||||
|
; Delete
|
||||||
|
;
|
||||||
|
MSG_GAD_TOOL
|
||||||
|
Værktøj
|
||||||
|
; Tool
|
||||||
|
;
|
||||||
|
MSG_INFO_1
|
||||||
|
Værktøjer kan tilføjes
|
||||||
|
; You can add tools
|
||||||
|
;
|
||||||
|
MSG_INFO_2
|
||||||
|
ved at trække deres ikoner
|
||||||
|
; by dragging their icons
|
||||||
|
;
|
||||||
|
MSG_INFO_3
|
||||||
|
ind i dette vindue.
|
||||||
|
; into this window.
|
||||||
|
;
|
|
@ -0,0 +1,51 @@
|
||||||
|
/*
|
||||||
|
ToolsMenu - Add tools to the Workbench Tools menu
|
||||||
|
|
||||||
|
Copyright (C) 2015, 2018 Kim Fastrup Larsen
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation, either ver-
|
||||||
|
sion 3 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be use-
|
||||||
|
ful, but WITHOUT ANY WARRANTY; without even the implied war-
|
||||||
|
ranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
See the GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public Li-
|
||||||
|
cense along with this program. If not, see
|
||||||
|
<http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
The author can be contacted on <kimflarsen@hotmail.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <intuition/intuition.h>
|
||||||
|
|
||||||
|
#include <clib/intuition_protos.h>
|
||||||
|
|
||||||
|
#ifdef USE_PRAGMAS
|
||||||
|
#include <proto/intuition.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define CATCOMP_NUMBERS
|
||||||
|
|
||||||
|
#include "catalog.h"
|
||||||
|
#include "common.h"
|
||||||
|
#include "error.h"
|
||||||
|
#include "strings.h"
|
||||||
|
|
||||||
|
extern struct IntuitionBase *IntuitionBase;
|
||||||
|
|
||||||
|
void error_message(char *fmt, char *arg)
|
||||||
|
{
|
||||||
|
static struct EasyStruct easy_struct = {
|
||||||
|
sizeof(struct EasyStruct), 0, APP_NAME
|
||||||
|
};
|
||||||
|
|
||||||
|
if (IntuitionBase == NULL)
|
||||||
|
return;
|
||||||
|
easy_struct.es_TextFormat = fmt;
|
||||||
|
easy_struct.es_GadgetFormat = get_string(MSG_GAD_CONTINUE);
|
||||||
|
EasyRequestArgs(NULL, &easy_struct, NULL, &arg);
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
/*
|
||||||
|
ToolsMenu - Add tools to the Workbench Tools menu
|
||||||
|
|
||||||
|
Copyright (C) 2015, 2018 Kim Fastrup Larsen
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation, either ver-
|
||||||
|
sion 3 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be use-
|
||||||
|
ful, but WITHOUT ANY WARRANTY; without even the implied war-
|
||||||
|
ranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
See the GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public Li-
|
||||||
|
cense along with this program. If not, see
|
||||||
|
<http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
The author can be contacted on <kimflarsen@hotmail.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef ERROR_H
|
||||||
|
#define ERROR_H
|
||||||
|
|
||||||
|
/* fmt can contain up to one %s.
|
||||||
|
If fmt contains a %s, arg must be non-NULL.
|
||||||
|
*/
|
||||||
|
void error_message(char *fmt, char *arg);
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,618 @@
|
||||||
|
/*
|
||||||
|
ToolsMenu - Add tools to the Workbench Tools menu
|
||||||
|
|
||||||
|
Copyright (C) 2015, 2018 Kim Fastrup Larsen
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation, either ver-
|
||||||
|
sion 3 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be use-
|
||||||
|
ful, but WITHOUT ANY WARRANTY; without even the implied war-
|
||||||
|
ranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
See the GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public Li-
|
||||||
|
cense along with this program. If not, see
|
||||||
|
<http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
The author can be contacted on <kimflarsen@hotmail.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define INTUI_V36_NAMES_ONLY
|
||||||
|
|
||||||
|
#include <dos/dos.h>
|
||||||
|
#include <exec/memory.h>
|
||||||
|
#include <exec/ports.h>
|
||||||
|
#include <intuition/gadgetclass.h>
|
||||||
|
#include <intuition/intuition.h>
|
||||||
|
#include <intuition/intuitionbase.h>
|
||||||
|
#include <libraries/gadtools.h>
|
||||||
|
|
||||||
|
#include <clib/exec_protos.h>
|
||||||
|
#include <clib/gadtools_protos.h>
|
||||||
|
#include <clib/intuition_protos.h>
|
||||||
|
|
||||||
|
#ifdef USE_PRAGMAS
|
||||||
|
#include <proto/exec.h>
|
||||||
|
#include <proto/gadtools.h>
|
||||||
|
#include <proto/intuition.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <strings.h>
|
||||||
|
|
||||||
|
#define CATCOMP_NUMBERS
|
||||||
|
|
||||||
|
#include "args.h"
|
||||||
|
#include "catalog.h"
|
||||||
|
#include "common.h"
|
||||||
|
#include "compiler.h"
|
||||||
|
#include "cx.h"
|
||||||
|
#include "gui.h"
|
||||||
|
#include "message.h"
|
||||||
|
#include "strings.h"
|
||||||
|
#include "wb.h"
|
||||||
|
|
||||||
|
#define NOT_SET 0xffffffffU
|
||||||
|
|
||||||
|
#define GAD_ID_LIST 1
|
||||||
|
#define GAD_ID_NEW 2
|
||||||
|
#define GAD_ID_DELETE 3
|
||||||
|
#define GAD_ID_NAME 4
|
||||||
|
#define GAD_ID_PATH 5
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int line_h;
|
||||||
|
int col1_x;
|
||||||
|
int list_y, list_w, list_h, scro_w;
|
||||||
|
int gadg_h;
|
||||||
|
int name_y, butn_y;
|
||||||
|
int col2_x;
|
||||||
|
int path_y, path_w;
|
||||||
|
int wind_w, wind_h;
|
||||||
|
int text_y;
|
||||||
|
} Layout;
|
||||||
|
|
||||||
|
extern struct IntuitionBase *IntuitionBase;
|
||||||
|
|
||||||
|
static struct IntuiText itexts[3] = {
|
||||||
|
{ 0, 0, JAM1, 0, 0, NULL, NULL, itexts + 1 },
|
||||||
|
{ 0, 0, JAM1, 0, 0, NULL, NULL, itexts + 2 },
|
||||||
|
{ 0, 0, JAM1, 0, 0, NULL, NULL, NULL }
|
||||||
|
};
|
||||||
|
static WORD zoom[4];
|
||||||
|
|
||||||
|
static struct MsgPort *user_port;
|
||||||
|
static struct Menu *menus;
|
||||||
|
static struct Requester busy_req;
|
||||||
|
static Message message;
|
||||||
|
static Bool message_constructed;
|
||||||
|
static struct Screen *screen;
|
||||||
|
static struct DrawInfo *draw_info;
|
||||||
|
static APTR visual_info;
|
||||||
|
static struct Gadget *gadgets;
|
||||||
|
static struct Window *window;
|
||||||
|
static struct AppWindow *app_window;
|
||||||
|
|
||||||
|
static ULONG left_edge;
|
||||||
|
static ULONG top_edge = NOT_SET;
|
||||||
|
|
||||||
|
static struct Gadget *list_gad, *name_gad, *del_gad, *path_gad;
|
||||||
|
|
||||||
|
static Tool *current;
|
||||||
|
|
||||||
|
static UBYTE *strgad_buf(struct Gadget *gadget)
|
||||||
|
{
|
||||||
|
return ((struct StringInfo *) gadget->SpecialInfo)->Buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void strip_messages_for(struct Window *window)
|
||||||
|
{
|
||||||
|
struct IntuiMessage *msg, *succ;
|
||||||
|
|
||||||
|
msg = (struct IntuiMessage *) window->UserPort->mp_MsgList.lh_Head;
|
||||||
|
while ((succ = (struct IntuiMessage *) msg->ExecMessage.mn_Node.ln_Succ)
|
||||||
|
!= NULL) {
|
||||||
|
if (msg->IDCMPWindow == window) {
|
||||||
|
Remove(&msg->ExecMessage.mn_Node);
|
||||||
|
ReplyMsg(&msg->ExecMessage);
|
||||||
|
}
|
||||||
|
msg = succ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void close_window_safely(struct Window *window)
|
||||||
|
{
|
||||||
|
Forbid();
|
||||||
|
strip_messages_for(window);
|
||||||
|
window->UserPort = NULL;
|
||||||
|
ModifyIDCMP(window, 0);
|
||||||
|
Permit();
|
||||||
|
CloseWindow(window);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Bool set_up_menus(void)
|
||||||
|
{
|
||||||
|
static struct NewMenu new_menus[] = {
|
||||||
|
{ NM_TITLE, NULL, NULL, 0, 0, (APTR) MSG_PROJECT_MENU },
|
||||||
|
{ NM_ITEM, NULL, "S", 0, 0, (APTR) MSG_PROJECT_SAVE },
|
||||||
|
{ NM_ITEM, NM_BARLABEL, NULL, 0, 0, NULL },
|
||||||
|
{ NM_ITEM, NULL, "H", 0, 0, (APTR) MSG_PROJECT_HIDE },
|
||||||
|
{ NM_ITEM, NULL, NULL, 0, 0, (APTR) MSG_PROJECT_ABOUT },
|
||||||
|
{ NM_ITEM, NULL, "Q", 0, 0, (APTR) MSG_PROJECT_QUIT },
|
||||||
|
{ NM_END, NULL, NULL, 0, 0, NULL }
|
||||||
|
};
|
||||||
|
struct NewMenu *nm;
|
||||||
|
|
||||||
|
for (nm = new_menus; nm->nm_Type != NM_END; ++nm)
|
||||||
|
if (nm->nm_UserData != NULL)
|
||||||
|
nm->nm_Label = get_string((ULONG) nm->nm_UserData);
|
||||||
|
if ((menus = CreateMenus(new_menus, TAG_DONE)) == NULL)
|
||||||
|
return NO;
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void render(void)
|
||||||
|
{
|
||||||
|
PrintIText(window->RPort, itexts, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void make_layout(Layout *layout)
|
||||||
|
{
|
||||||
|
int font_w = draw_info->dri_Font->tf_XSize;
|
||||||
|
int font_h = draw_info->dri_Font->tf_YSize;
|
||||||
|
int pad_x = font_w;
|
||||||
|
int pad_y = font_h / 2;
|
||||||
|
int lab_h = font_h + 4; /* space taken up by label above a gadget */
|
||||||
|
int path_th; /* total height of path gadget and label above */
|
||||||
|
int col2_spc; /* vertical spacing around path gadget and text */
|
||||||
|
|
||||||
|
layout->line_h = font_h + 1;
|
||||||
|
layout->col1_x = pad_x;
|
||||||
|
layout->list_y = pad_y + lab_h;
|
||||||
|
layout->list_w = 24 * font_w + 12; /* should be divisible by 2 */
|
||||||
|
layout->list_h = 6 * layout->line_h + 4;
|
||||||
|
layout->scro_w = font_w + 10;
|
||||||
|
layout->gadg_h = font_h + 6;
|
||||||
|
layout->name_y = layout->list_y + layout->list_h;
|
||||||
|
layout->butn_y = layout->name_y + layout->gadg_h;
|
||||||
|
layout->col2_x = layout->col1_x + layout->list_w + pad_x;
|
||||||
|
layout->path_w = 32 * font_w + 12;
|
||||||
|
layout->wind_w = layout->col2_x + layout->path_w + pad_x;
|
||||||
|
layout->wind_h = layout->butn_y + layout->gadg_h + pad_y;
|
||||||
|
path_th = layout->gadg_h + lab_h;
|
||||||
|
col2_spc = (layout->wind_h - path_th - 3 * layout->line_h) / 3;
|
||||||
|
layout->path_y = col2_spc + lab_h;
|
||||||
|
layout->text_y = 2 * col2_spc + path_th;
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned window_border_top(void)
|
||||||
|
{
|
||||||
|
return screen->WBorTop + screen->Font->ta_YSize + 1U;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void make_newgadget(struct NewGadget *ng, WORD left_edge,
|
||||||
|
WORD top_edge, WORD width, WORD height, UBYTE *gadget_text, UWORD id,
|
||||||
|
ULONG flags)
|
||||||
|
{
|
||||||
|
ng->ng_LeftEdge = left_edge + screen->WBorLeft;
|
||||||
|
ng->ng_TopEdge = top_edge + window_border_top();
|
||||||
|
ng->ng_Width = width;
|
||||||
|
ng->ng_Height = height;
|
||||||
|
ng->ng_GadgetText = gadget_text;
|
||||||
|
ng->ng_GadgetID = id;
|
||||||
|
ng->ng_Flags = flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Bool create_gadgets(Layout *l)
|
||||||
|
{
|
||||||
|
struct NewGadget ng;
|
||||||
|
struct Gadget *g = CreateContext(&gadgets);
|
||||||
|
int butn_w = l->list_w / 2;
|
||||||
|
|
||||||
|
ng.ng_TextAttr = screen->Font;
|
||||||
|
ng.ng_VisualInfo = visual_info;
|
||||||
|
make_newgadget(&ng, l->col1_x, l->list_y, l->list_w, l->list_h,
|
||||||
|
get_string(MSG_GAD_MENU_ITEMS), GAD_ID_LIST, 0);
|
||||||
|
g = list_gad = CreateGadget(LISTVIEW_KIND, g, &ng,
|
||||||
|
GTLV_Labels, tools,
|
||||||
|
GTLV_ScrollWidth, (LONG) l->scro_w,
|
||||||
|
LAYOUTA_Spacing, 1L,
|
||||||
|
TAG_DONE);
|
||||||
|
make_newgadget(&ng, l->col1_x, l->name_y, l->list_w, l->gadg_h,
|
||||||
|
NULL, GAD_ID_NAME, 0);
|
||||||
|
g = name_gad = CreateGadget(STRING_KIND, g, &ng,
|
||||||
|
GA_Disabled, (LONG) TRUE,
|
||||||
|
TAG_DONE);
|
||||||
|
make_newgadget(&ng, l->col1_x, l->butn_y, butn_w, l->gadg_h,
|
||||||
|
get_string(MSG_GAD_NEW), GAD_ID_NEW, 0);
|
||||||
|
g = CreateGadget(BUTTON_KIND, g, &ng,
|
||||||
|
TAG_DONE);
|
||||||
|
make_newgadget(&ng, l->col1_x + butn_w, l->butn_y, butn_w, l->gadg_h,
|
||||||
|
get_string(MSG_GAD_DELETE), GAD_ID_DELETE, 0);
|
||||||
|
g = del_gad = CreateGadget(BUTTON_KIND, g, &ng,
|
||||||
|
GA_Disabled, (LONG) TRUE,
|
||||||
|
TAG_DONE);
|
||||||
|
make_newgadget(&ng, l->col2_x, l->path_y, l->path_w, l->gadg_h,
|
||||||
|
get_string(MSG_GAD_TOOL), GAD_ID_PATH, PLACETEXT_ABOVE);
|
||||||
|
g = path_gad = CreateGadget(STRING_KIND, g, &ng,
|
||||||
|
GTST_MaxChars, (LONG) MAX_PATH_LENGTH,
|
||||||
|
GA_Disabled, (LONG) TRUE,
|
||||||
|
TAG_DONE);
|
||||||
|
return g != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void layout_texts(Layout *layout)
|
||||||
|
{
|
||||||
|
int left_edge = layout->col2_x;
|
||||||
|
int top_edge = layout->text_y + window_border_top();
|
||||||
|
struct IntuiText *t;
|
||||||
|
|
||||||
|
for (t = itexts; t != NULL; t = t->NextText) {
|
||||||
|
t->FrontPen = draw_info->dri_Pens[TEXTPEN];
|
||||||
|
t->ITextFont = screen->Font;
|
||||||
|
t->LeftEdge = left_edge + (layout->path_w - IntuiTextLength(t)) / 2;
|
||||||
|
t->TopEdge = top_edge;
|
||||||
|
top_edge += layout->line_h;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static Bool open_window(Layout *layout)
|
||||||
|
{
|
||||||
|
static char window_title_buf[64];
|
||||||
|
char *window_title = get_string(MSG_WINDOW_TITLE);
|
||||||
|
|
||||||
|
if (strlen(window_title)+strlen(APP_NAME)+strlen(args.cx_popkey) > 64)
|
||||||
|
window_title = APP_NAME;
|
||||||
|
else {
|
||||||
|
sprintf(window_title_buf, window_title, APP_NAME, args.cx_popkey);
|
||||||
|
window_title = window_title_buf;
|
||||||
|
}
|
||||||
|
if ((window = OpenWindowTags(NULL,
|
||||||
|
WA_Left, left_edge,
|
||||||
|
WA_Top, top_edge,
|
||||||
|
WA_InnerWidth, (LONG) layout->wind_w,
|
||||||
|
WA_InnerHeight, (LONG) layout->wind_h,
|
||||||
|
WA_Flags, (ULONG) WFLG_DRAGBAR | WFLG_DEPTHGADGET | WFLG_CLOSEGADGET |
|
||||||
|
WFLG_ACTIVATE | WFLG_SIMPLE_REFRESH,
|
||||||
|
WA_PubScreen, screen,
|
||||||
|
WA_Zoom, zoom,
|
||||||
|
WA_Gadgets, gadgets,
|
||||||
|
WA_Title, window_title,
|
||||||
|
WA_AutoAdjust, (LONG) TRUE,
|
||||||
|
WA_NewLookMenus, (LONG) TRUE,
|
||||||
|
TAG_DONE)) == NULL)
|
||||||
|
return NO;
|
||||||
|
window->UserPort = user_port;
|
||||||
|
ModifyIDCMP(window, IDCMP_CLOSEWINDOW | IDCMP_MENUPICK | IDCMP_REFRESHWINDOW
|
||||||
|
| LISTVIEWIDCMP | STRINGIDCMP | BUTTONIDCMP);
|
||||||
|
GT_RefreshWindow(window, NULL);
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void update_gadgets(void)
|
||||||
|
{
|
||||||
|
Bool disable = (current == NULL);
|
||||||
|
|
||||||
|
GT_SetGadgetAttrs(name_gad, window, NULL,
|
||||||
|
GA_Disabled, (LONG) disable,
|
||||||
|
GTST_String, disable ? "" : current->node.ln_Name,
|
||||||
|
TAG_DONE);
|
||||||
|
GT_SetGadgetAttrs(del_gad, window, NULL,
|
||||||
|
GA_Disabled, (LONG) disable,
|
||||||
|
TAG_DONE);
|
||||||
|
GT_SetGadgetAttrs(path_gad, window, NULL,
|
||||||
|
GA_Disabled, (LONG) disable,
|
||||||
|
GTST_String, disable ? "" : current->path,
|
||||||
|
TAG_DONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void update_current(void)
|
||||||
|
{
|
||||||
|
if (current == NULL)
|
||||||
|
return;
|
||||||
|
if ((current = cx_modify_tool(current, strgad_buf(name_gad),
|
||||||
|
strgad_buf(path_gad))) == NULL)
|
||||||
|
update_gadgets();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void select(int index)
|
||||||
|
{
|
||||||
|
gui_edit((Tool *) node_at(tools, index));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void new_tool(void)
|
||||||
|
{
|
||||||
|
cx_add_tool("", "");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void delete_tool(void)
|
||||||
|
{
|
||||||
|
GT_SetGadgetAttrs(name_gad, window, NULL,
|
||||||
|
GTST_String, "",
|
||||||
|
TAG_DONE);
|
||||||
|
update_current();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void handle_gadgetup(struct Gadget *gadget, UWORD code)
|
||||||
|
{
|
||||||
|
switch (gadget->GadgetID) {
|
||||||
|
case GAD_ID_LIST:
|
||||||
|
select(code);
|
||||||
|
break;
|
||||||
|
case GAD_ID_NEW:
|
||||||
|
new_tool();
|
||||||
|
break;
|
||||||
|
case GAD_ID_DELETE:
|
||||||
|
delete_tool();
|
||||||
|
break;
|
||||||
|
case GAD_ID_NAME:
|
||||||
|
case GAD_ID_PATH:
|
||||||
|
update_current();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void handle_project_menu(UWORD code)
|
||||||
|
{
|
||||||
|
switch (ITEMNUM(code)) {
|
||||||
|
case 0: /* Save Menu Items */
|
||||||
|
cx_save_tools();
|
||||||
|
break;
|
||||||
|
case 2: /* Hide */
|
||||||
|
cx_hide();
|
||||||
|
break;
|
||||||
|
case 3: /* About */
|
||||||
|
cx_about();
|
||||||
|
break;
|
||||||
|
case 4: /* Quit */
|
||||||
|
cx_quit();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void handle_menupick(UWORD code)
|
||||||
|
{
|
||||||
|
while (code != MENUNULL) {
|
||||||
|
switch (MENUNUM(code)) {
|
||||||
|
case 0:
|
||||||
|
handle_project_menu(code);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
code = ItemAddress(menus, code)->NextSelect;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void handle_closewindow(void)
|
||||||
|
{
|
||||||
|
cx_hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void handle_refreshwindow(void)
|
||||||
|
{
|
||||||
|
GT_BeginRefresh(window);
|
||||||
|
render();
|
||||||
|
GT_EndRefresh(window, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void bring_to_front(void)
|
||||||
|
{
|
||||||
|
ScreenToFront(window->WScreen);
|
||||||
|
WindowToFront(window);
|
||||||
|
ActivateWindow(window);
|
||||||
|
if (window->Height == zoom[3])
|
||||||
|
ZipWindow(window);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void fill_itexts(struct IntuiText *text, va_list *ap)
|
||||||
|
{
|
||||||
|
char *s;
|
||||||
|
|
||||||
|
while ((s = va_arg(*ap, char *)) != NULL) {
|
||||||
|
text->IText = s;
|
||||||
|
text->NextText = text + 1;
|
||||||
|
++text;
|
||||||
|
}
|
||||||
|
(text - 1)->NextText = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ULONG gui_set_up()
|
||||||
|
{
|
||||||
|
if (IntuitionBase->LibNode.lib_Version >= 39)
|
||||||
|
zoom[0] = zoom[1] = ~0;
|
||||||
|
if (!set_up_menus())
|
||||||
|
exit(RETURN_FAIL);
|
||||||
|
if ((user_port = CreateMsgPort()) == NULL)
|
||||||
|
exit(RETURN_FAIL);
|
||||||
|
itexts[0].IText = get_string(MSG_INFO_1);
|
||||||
|
itexts[1].IText = get_string(MSG_INFO_2);
|
||||||
|
itexts[2].IText = get_string(MSG_INFO_3);
|
||||||
|
InitRequester(&busy_req);
|
||||||
|
if (!message_cons(&message))
|
||||||
|
exit(RETURN_FAIL);
|
||||||
|
message_constructed = YES;
|
||||||
|
return 1UL << user_port->mp_SigBit;
|
||||||
|
}
|
||||||
|
|
||||||
|
void gui_clean_up()
|
||||||
|
{
|
||||||
|
if (message_constructed)
|
||||||
|
message_dest(&message);
|
||||||
|
DeleteMsgPort(user_port);
|
||||||
|
if (menus != NULL) /* Really checking if gadtools.library was opened */
|
||||||
|
FreeMenus(menus);
|
||||||
|
}
|
||||||
|
|
||||||
|
void gui_handle_signal()
|
||||||
|
{
|
||||||
|
struct IntuiMessage *imsg;
|
||||||
|
ULONG clas;
|
||||||
|
UWORD code;
|
||||||
|
APTR iadd;
|
||||||
|
|
||||||
|
while ((imsg = GT_GetIMsg(user_port)) != NULL) {
|
||||||
|
clas = imsg->Class;
|
||||||
|
code = imsg->Code;
|
||||||
|
iadd = imsg->IAddress;
|
||||||
|
GT_ReplyIMsg(imsg);
|
||||||
|
switch (clas) {
|
||||||
|
case IDCMP_MENUPICK:
|
||||||
|
handle_menupick(code);
|
||||||
|
break;
|
||||||
|
case IDCMP_CLOSEWINDOW:
|
||||||
|
handle_closewindow();
|
||||||
|
break;
|
||||||
|
case IDCMP_REFRESHWINDOW:
|
||||||
|
handle_refreshwindow();
|
||||||
|
break;
|
||||||
|
case IDCMP_GADGETUP:
|
||||||
|
handle_gadgetup(iadd, code);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void gui_show()
|
||||||
|
{
|
||||||
|
Layout layout;
|
||||||
|
|
||||||
|
if (window != NULL) {
|
||||||
|
bring_to_front();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if ((screen = LockPubScreen(NULL)) == NULL)
|
||||||
|
goto gui_show_failed;
|
||||||
|
ScreenToFront(screen);
|
||||||
|
if ((draw_info = GetScreenDrawInfo(screen)) == NULL)
|
||||||
|
goto gui_show_failed;
|
||||||
|
if ((visual_info = GetVisualInfo(screen, TAG_DONE)) == NULL)
|
||||||
|
goto gui_show_failed;
|
||||||
|
if (!LayoutMenus(menus, visual_info,
|
||||||
|
GTMN_NewLookMenus, (LONG) TRUE,
|
||||||
|
TAG_DONE))
|
||||||
|
goto gui_show_failed;
|
||||||
|
if (top_edge == NOT_SET)
|
||||||
|
top_edge = screen->BarHeight + 1;
|
||||||
|
zoom[2] = 25 * draw_info->dri_Font->tf_XSize;
|
||||||
|
zoom[3] = window_border_top();
|
||||||
|
make_layout(&layout);
|
||||||
|
if (!create_gadgets(&layout))
|
||||||
|
goto gui_show_failed;
|
||||||
|
layout_texts(&layout);
|
||||||
|
if (!open_window(&layout))
|
||||||
|
goto gui_show_failed;
|
||||||
|
render();
|
||||||
|
app_window = wb_add_window(window);
|
||||||
|
SetMenuStrip(window, menus);
|
||||||
|
current = NULL;
|
||||||
|
return;
|
||||||
|
|
||||||
|
gui_show_failed:
|
||||||
|
gui_hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
void gui_hide()
|
||||||
|
{
|
||||||
|
if (app_window != NULL) {
|
||||||
|
wb_remove_window(app_window);
|
||||||
|
app_window = NULL;
|
||||||
|
}
|
||||||
|
if (window != NULL) {
|
||||||
|
EndRequest(&message.requester, window);
|
||||||
|
if (window->MenuStrip != NULL)
|
||||||
|
ClearMenuStrip(window);
|
||||||
|
left_edge = window->LeftEdge;
|
||||||
|
top_edge = window->TopEdge;
|
||||||
|
close_window_safely(window);
|
||||||
|
window = NULL;
|
||||||
|
}
|
||||||
|
FreeGadgets(gadgets);
|
||||||
|
gadgets = NULL;
|
||||||
|
FreeVisualInfo(visual_info);
|
||||||
|
visual_info = NULL;
|
||||||
|
if (screen != NULL) {
|
||||||
|
FreeScreenDrawInfo(screen, draw_info);
|
||||||
|
draw_info = NULL;
|
||||||
|
UnlockPubScreen(NULL, screen);
|
||||||
|
screen = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void gui_edit(Tool *tool)
|
||||||
|
{
|
||||||
|
if (window == NULL)
|
||||||
|
return;
|
||||||
|
current = tool;
|
||||||
|
update_gadgets();
|
||||||
|
if (current != NULL)
|
||||||
|
ActivateGadget(name_gad, window, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Temporarily suspend the listview so we can update the list. */
|
||||||
|
void gui_begin_update()
|
||||||
|
{
|
||||||
|
if (window == NULL)
|
||||||
|
return;
|
||||||
|
GT_SetGadgetAttrs(list_gad, window, NULL, GTLV_Labels, ~0L, TAG_DONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Resume normal listview operations. */
|
||||||
|
void gui_end_update()
|
||||||
|
{
|
||||||
|
if (window == NULL)
|
||||||
|
return;
|
||||||
|
GT_SetGadgetAttrs(list_gad, window, NULL, GTLV_Labels, tools, TAG_DONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void gui_begin_busy()
|
||||||
|
{
|
||||||
|
static UWORD CHIP busy_pointer[] = {
|
||||||
|
0x0000, 0x0000, 0x0400, 0x07c0, 0x0000, 0x07c0, 0x0100, 0x0380,
|
||||||
|
0x0000, 0x07e0, 0x07c0, 0x1ff8, 0x1ff0, 0x3fec, 0x3ff8, 0x7fde,
|
||||||
|
0x3ff8, 0x7fbe, 0x7ffc, 0xff7f, 0x7efc, 0xffff, 0x7ffc, 0xffff,
|
||||||
|
0x3ff8, 0x7ffe, 0x3ff8, 0x7ffe, 0x1ff0, 0x3ffc, 0x07c0, 0x1ff8,
|
||||||
|
0x0000, 0x07e0, 0x0000, 0x0000
|
||||||
|
};
|
||||||
|
|
||||||
|
if (window == NULL)
|
||||||
|
return;
|
||||||
|
Request(&busy_req, window);
|
||||||
|
if (IntuitionBase->LibNode.lib_Version < 39)
|
||||||
|
SetPointer(window, busy_pointer, 16, 16, -6, 0);
|
||||||
|
else
|
||||||
|
SetWindowPointer(window,
|
||||||
|
WA_BusyPointer, (LONG) TRUE,
|
||||||
|
WA_PointerDelay, (LONG) TRUE,
|
||||||
|
TAG_DONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void gui_end_busy()
|
||||||
|
{
|
||||||
|
if (window == NULL)
|
||||||
|
return;
|
||||||
|
if (IntuitionBase->LibNode.lib_Version < 39)
|
||||||
|
ClearPointer(window);
|
||||||
|
else
|
||||||
|
SetWindowPointer(window, TAG_DONE);
|
||||||
|
EndRequest(&busy_req, window);
|
||||||
|
}
|
||||||
|
|
||||||
|
void gui_message(char *button_text, ...)
|
||||||
|
{
|
||||||
|
static struct IntuiText texts[GUI_MESSAGE_MAX_LINES];
|
||||||
|
va_list ap;
|
||||||
|
|
||||||
|
va_start(ap, button_text);
|
||||||
|
if (window == NULL || message.requester.Flags & REQACTIVE)
|
||||||
|
goto gui_message_exit;
|
||||||
|
fill_itexts(texts, &ap);
|
||||||
|
message_layout(&message, window, draw_info, texts, button_text);
|
||||||
|
Request(&message.requester, window);
|
||||||
|
|
||||||
|
gui_message_exit:
|
||||||
|
va_end(ap);
|
||||||
|
}
|
|
@ -0,0 +1,44 @@
|
||||||
|
/*
|
||||||
|
ToolsMenu - Add tools to the Workbench Tools menu
|
||||||
|
|
||||||
|
Copyright (C) 2015, 2018 Kim Fastrup Larsen
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation, either ver-
|
||||||
|
sion 3 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be use-
|
||||||
|
ful, but WITHOUT ANY WARRANTY; without even the implied war-
|
||||||
|
ranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
See the GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public Li-
|
||||||
|
cense along with this program. If not, see
|
||||||
|
<http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
The author can be contacted on <kimflarsen@hotmail.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef GUI_H
|
||||||
|
#define GUI_H
|
||||||
|
|
||||||
|
#include <exec/types.h>
|
||||||
|
|
||||||
|
#include "cx.h"
|
||||||
|
|
||||||
|
#define GUI_MESSAGE_MAX_LINES 6
|
||||||
|
|
||||||
|
ULONG gui_set_up(void);
|
||||||
|
void gui_clean_up(void);
|
||||||
|
void gui_handle_signal(void);
|
||||||
|
void gui_show(void);
|
||||||
|
void gui_hide(void);
|
||||||
|
void gui_edit(Tool *);
|
||||||
|
void gui_begin_update(void);
|
||||||
|
void gui_end_update(void);
|
||||||
|
void gui_begin_busy(void);
|
||||||
|
void gui_end_busy(void);
|
||||||
|
void gui_message(char *button_text, ...);
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,162 @@
|
||||||
|
/*
|
||||||
|
ToolsMenu - Add tools to the Workbench Tools menu
|
||||||
|
|
||||||
|
Copyright (C) 2015, 2018 Kim Fastrup Larsen
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation, either ver-
|
||||||
|
sion 3 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be use-
|
||||||
|
ful, but WITHOUT ANY WARRANTY; without even the implied war-
|
||||||
|
ranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
See the GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public Li-
|
||||||
|
cense along with this program. If not, see
|
||||||
|
<http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
The author can be contacted on <kimflarsen@hotmail.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <exec/memory.h>
|
||||||
|
|
||||||
|
#include <clib/dos_protos.h>
|
||||||
|
#include <clib/exec_protos.h>
|
||||||
|
#include <clib/icon_protos.h>
|
||||||
|
|
||||||
|
#ifdef USE_PRAGMAS
|
||||||
|
#include <proto/dos.h>
|
||||||
|
#include <proto/exec.h>
|
||||||
|
#include <proto/icon.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
#include "cx.h"
|
||||||
|
#include "io.h"
|
||||||
|
|
||||||
|
#define DEF_BEGIN '\xab' /* Left double angle quote */
|
||||||
|
#define DEF_END '\xbb' /* Right double angle quote */
|
||||||
|
|
||||||
|
typedef void Disk_object_f(struct DiskObject *, char *);
|
||||||
|
|
||||||
|
static void with_disk_object(Disk_object_f *f, BPTR dir, char *filename)
|
||||||
|
{
|
||||||
|
BPTR old_dir = CurrentDir(dir);
|
||||||
|
struct DiskObject *disk_obj = GetDiskObject(filename);
|
||||||
|
|
||||||
|
if (disk_obj != NULL) {
|
||||||
|
(*f)(disk_obj, filename);
|
||||||
|
FreeDiskObject(disk_obj);
|
||||||
|
}
|
||||||
|
CurrentDir(old_dir);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void read_definitions(struct DiskObject *disk_obj, char *filename)
|
||||||
|
{
|
||||||
|
char **tt, *def_end;
|
||||||
|
|
||||||
|
for (tt = disk_obj->do_ToolTypes; *tt != NULL; ++tt)
|
||||||
|
/* Identify the tool types that are menu item definitions and create
|
||||||
|
menu items from them. */
|
||||||
|
if (**tt == DEF_BEGIN && (def_end = strchr(*tt, DEF_END)) != NULL &&
|
||||||
|
*(def_end + 1) == ' ') {
|
||||||
|
/* Temporarily insert terminator to facilitate string copy. */
|
||||||
|
*def_end = '\0';
|
||||||
|
cx_add_tool(*tt + 1, def_end + 2);
|
||||||
|
/* Restore original char to leave string "untouched". */
|
||||||
|
*def_end = DEF_END;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Count the number of tool types that are not menu item definitions. */
|
||||||
|
static int non_defs(char **tt)
|
||||||
|
{
|
||||||
|
int result = 0;
|
||||||
|
|
||||||
|
for ( ; *tt != NULL; ++tt)
|
||||||
|
if (**tt != DEF_BEGIN)
|
||||||
|
++result;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create a tool type for a menu item definition. */
|
||||||
|
static char *create_def(Tool *t)
|
||||||
|
{
|
||||||
|
char *def;
|
||||||
|
size_t name_len = strlen(t->node.ln_Name);
|
||||||
|
|
||||||
|
/* Allocate space for name, path, two delimiters, a space, and
|
||||||
|
string terminator */
|
||||||
|
def = AllocVec(name_len + strlen(t->path) + 4, 0);
|
||||||
|
if (def != NULL) {
|
||||||
|
def[0] = DEF_BEGIN;
|
||||||
|
strcpy(def + 1, t->node.ln_Name);
|
||||||
|
def[name_len + 1] = DEF_END;
|
||||||
|
def[name_len + 2] = ' ';
|
||||||
|
strcpy(def + name_len + 3, t->path);
|
||||||
|
}
|
||||||
|
return def;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create a tool type for every menu item in the tools list. */
|
||||||
|
static Bool create_defs(char **tt)
|
||||||
|
{
|
||||||
|
struct Node *n;
|
||||||
|
|
||||||
|
for (n = tools->lh_Head; n->ln_Succ != NULL; n = n->ln_Succ)
|
||||||
|
if ((*(tt++) = create_def((Tool *) n)) == NULL)
|
||||||
|
return NO;
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Copy over those tool types that are not menu item definitions. */
|
||||||
|
static void copy_non_defs(char **new_tt, char **old_tt)
|
||||||
|
{
|
||||||
|
for ( ; *old_tt != NULL; ++old_tt)
|
||||||
|
if (**old_tt != DEF_BEGIN)
|
||||||
|
*(new_tt++) = *old_tt;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void free_tool_types(char **tt)
|
||||||
|
{
|
||||||
|
char **i;
|
||||||
|
|
||||||
|
for (i = tt ; *i != NULL; ++i)
|
||||||
|
if (**i == DEF_BEGIN)
|
||||||
|
FreeVec(*i);
|
||||||
|
FreeVec(tt);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void write_definitions(struct DiskObject *disk_obj, char *filename)
|
||||||
|
{
|
||||||
|
int tools_size = length_of(tools);
|
||||||
|
char **old_tool_types = disk_obj->do_ToolTypes;
|
||||||
|
int size = tools_size + non_defs(old_tool_types) + 1;
|
||||||
|
char **new_tool_types = AllocVec(sizeof(char *) * size, MEMF_CLEAR);
|
||||||
|
|
||||||
|
if (new_tool_types == NULL)
|
||||||
|
return;
|
||||||
|
if (!create_defs(new_tool_types))
|
||||||
|
goto write_definitions_exit;
|
||||||
|
copy_non_defs(new_tool_types + tools_size, old_tool_types);
|
||||||
|
disk_obj->do_ToolTypes = new_tool_types;
|
||||||
|
PutDiskObject(filename, disk_obj);
|
||||||
|
disk_obj->do_ToolTypes = old_tool_types;
|
||||||
|
|
||||||
|
write_definitions_exit:
|
||||||
|
free_tool_types(new_tool_types);
|
||||||
|
}
|
||||||
|
|
||||||
|
void io_read_definitions(BPTR dir, char *filename)
|
||||||
|
{
|
||||||
|
with_disk_object(read_definitions, dir, filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
void io_write_definitions(BPTR dir, char *filename)
|
||||||
|
{
|
||||||
|
with_disk_object(write_definitions, dir, filename);
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
/*
|
||||||
|
ToolsMenu - Add tools to the Workbench Tools menu
|
||||||
|
|
||||||
|
Copyright (C) 2015, 2018 Kim Fastrup Larsen
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation, either ver-
|
||||||
|
sion 3 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be use-
|
||||||
|
ful, but WITHOUT ANY WARRANTY; without even the implied war-
|
||||||
|
ranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
See the GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public Li-
|
||||||
|
cense along with this program. If not, see
|
||||||
|
<http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
The author can be contacted on <kimflarsen@hotmail.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef IO_H
|
||||||
|
#define IO_H
|
||||||
|
|
||||||
|
#include <dos/dos.h>
|
||||||
|
|
||||||
|
void io_read_definitions(BPTR dir, char *filename);
|
||||||
|
void io_write_definitions(BPTR dir, char *filename);
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,154 @@
|
||||||
|
/*
|
||||||
|
ToolsMenu - Add tools to the Workbench Tools menu
|
||||||
|
|
||||||
|
Copyright (C) 2015, 2018 Kim Fastrup Larsen
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation, either ver-
|
||||||
|
sion 3 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be use-
|
||||||
|
ful, but WITHOUT ANY WARRANTY; without even the implied war-
|
||||||
|
ranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
See the GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public Li-
|
||||||
|
cense along with this program. If not, see
|
||||||
|
<http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
The author can be contacted on <kimflarsen@hotmail.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <exec/libraries.h>
|
||||||
|
|
||||||
|
#include <clib/exec_protos.h>
|
||||||
|
|
||||||
|
#ifdef USE_PRAGMAS
|
||||||
|
#include <proto/exec.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#define CATCOMP_NUMBERS
|
||||||
|
|
||||||
|
#include "args.h"
|
||||||
|
#include "broker.h"
|
||||||
|
#include "catalog.h"
|
||||||
|
#include "error.h"
|
||||||
|
#include "gui.h"
|
||||||
|
#include "strings.h"
|
||||||
|
#include "toolrun.h"
|
||||||
|
#include "wb.h"
|
||||||
|
|
||||||
|
#define OS_REQUIRED 37
|
||||||
|
|
||||||
|
extern struct Library *SysBase;
|
||||||
|
extern struct Library *DOSBase;
|
||||||
|
|
||||||
|
char *version = "\0$VER: " TITLE " (" DATE ")";
|
||||||
|
|
||||||
|
struct Library *CxBase;
|
||||||
|
struct Library *GadToolsBase;
|
||||||
|
struct Library *IconBase;
|
||||||
|
struct Library *IntuitionBase;
|
||||||
|
struct Library *LocaleBase;
|
||||||
|
struct Library *WorkbenchBase;
|
||||||
|
|
||||||
|
static ULONG signals = SIGBREAKF_CTRL_C | SIGBREAKF_CTRL_F;
|
||||||
|
static ULONG wb_signal, tr_signal, broker_signal, gui_signal;
|
||||||
|
|
||||||
|
static void check_system_version(void)
|
||||||
|
{
|
||||||
|
if (SysBase->lib_Version<OS_REQUIRED||DOSBase->lib_Version<OS_REQUIRED)
|
||||||
|
exit(RETURN_FAIL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct Library *open_library(STRPTR name)
|
||||||
|
{
|
||||||
|
struct Library *base;
|
||||||
|
|
||||||
|
if ((base = OpenLibrary(name, OS_REQUIRED)) == NULL) {
|
||||||
|
error_message(get_string(MSG_ERR_OPEN), name);
|
||||||
|
exit(RETURN_FAIL);
|
||||||
|
}
|
||||||
|
return base;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void open_libraries(void)
|
||||||
|
{
|
||||||
|
IntuitionBase = open_library("intuition.library");
|
||||||
|
IconBase = open_library("icon.library");
|
||||||
|
CxBase = open_library("commodities.library");
|
||||||
|
GadToolsBase = open_library("gadtools.library");
|
||||||
|
WorkbenchBase = open_library("workbench.library");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void set_up(int argc, char **argv)
|
||||||
|
{
|
||||||
|
LocaleBase = OpenLibrary("locale.library", 38);
|
||||||
|
open_catalog(CATALOG);
|
||||||
|
open_libraries();
|
||||||
|
args_set_up(argc, argv);
|
||||||
|
signals |= wb_signal = wb_set_up();
|
||||||
|
signals |= tr_signal = tr_set_up();
|
||||||
|
signals |= broker_signal = broker_set_up();
|
||||||
|
signals |= gui_signal = gui_set_up();
|
||||||
|
cx_set_up();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void main_loop(void)
|
||||||
|
{
|
||||||
|
ULONG received;
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
received = Wait(signals);
|
||||||
|
if (received & wb_signal)
|
||||||
|
wb_handle_signal();
|
||||||
|
if (received & tr_signal)
|
||||||
|
tr_handle_signal();
|
||||||
|
if (received & broker_signal)
|
||||||
|
broker_handle_signal();
|
||||||
|
if (received & gui_signal)
|
||||||
|
gui_handle_signal();
|
||||||
|
if (received & SIGBREAKF_CTRL_C)
|
||||||
|
cx_quit();
|
||||||
|
if (received & SIGBREAKF_CTRL_F)
|
||||||
|
cx_show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void close_libraries(void)
|
||||||
|
{
|
||||||
|
CloseLibrary(WorkbenchBase);
|
||||||
|
CloseLibrary(GadToolsBase);
|
||||||
|
CloseLibrary(CxBase);
|
||||||
|
CloseLibrary(IconBase);
|
||||||
|
CloseLibrary(IntuitionBase);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Clean up as much as possible, then wait for the all tools started by us to
|
||||||
|
quit before finishing up. */
|
||||||
|
static void clean_up(void)
|
||||||
|
{
|
||||||
|
cx_clean_up();
|
||||||
|
gui_clean_up();
|
||||||
|
broker_clean_up();
|
||||||
|
/* tr_clean_up() won't return until all tools have quit. */
|
||||||
|
tr_clean_up();
|
||||||
|
wb_clean_up();
|
||||||
|
args_clean_up();
|
||||||
|
close_libraries();
|
||||||
|
close_catalog();
|
||||||
|
CloseLibrary(LocaleBase);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
check_system_version();
|
||||||
|
atexit(clean_up);
|
||||||
|
set_up(argc, argv);
|
||||||
|
if (args.cx_popup)
|
||||||
|
cx_show();
|
||||||
|
main_loop();
|
||||||
|
}
|
|
@ -0,0 +1,194 @@
|
||||||
|
/*
|
||||||
|
ToolsMenu - Add tools to the Workbench Tools menu
|
||||||
|
|
||||||
|
Copyright (C) 2015, 2018 Kim Fastrup Larsen
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation, either ver-
|
||||||
|
sion 3 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be use-
|
||||||
|
ful, but WITHOUT ANY WARRANTY; without even the implied war-
|
||||||
|
ranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
See the GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public Li-
|
||||||
|
cense along with this program. If not, see
|
||||||
|
<http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
The author can be contacted on <kimflarsen@hotmail.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define INTUI_V36_NAMES_ONLY
|
||||||
|
|
||||||
|
#include <intuition/imageclass.h>
|
||||||
|
#include <intuition/intuition.h>
|
||||||
|
|
||||||
|
#include <clib/intuition_protos.h>
|
||||||
|
|
||||||
|
#ifdef USE_PRAGMAS
|
||||||
|
#include <proto/intuition.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "message.h"
|
||||||
|
|
||||||
|
#define LINE_SPACING 1
|
||||||
|
|
||||||
|
static int max(int a, int b)
|
||||||
|
{
|
||||||
|
return (a > b) ? a : b;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void button_dest(Button *button)
|
||||||
|
{
|
||||||
|
DisposeObject(button->gadget.GadgetRender);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int button_cons(Button *button)
|
||||||
|
{
|
||||||
|
if ((button->gadget.GadgetRender = NewObject(NULL, "frameiclass",
|
||||||
|
TAG_DONE)) == NULL)
|
||||||
|
return 0;
|
||||||
|
button->text.DrawMode = JAM1;
|
||||||
|
button->text.NextText = NULL;
|
||||||
|
button->gadget.Flags = GFLG_GADGHIMAGE | GFLG_GADGIMAGE;
|
||||||
|
button->gadget.Activation = GACT_RELVERIFY | GACT_ENDGADGET;
|
||||||
|
button->gadget.GadgetType = GTYP_BOOLGADGET | GTYP_REQGADGET;
|
||||||
|
button->gadget.SelectRender = button->gadget.GadgetRender;
|
||||||
|
button->gadget.GadgetText = &button->text;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void button_layout(Button *button, struct TextAttr *font,
|
||||||
|
struct DrawInfo *draw_info, UBYTE *text)
|
||||||
|
{
|
||||||
|
button->text.LeftEdge = draw_info->dri_Font->tf_XSize;
|
||||||
|
button->text.TopEdge = draw_info->dri_Font->tf_YSize * 3 / 8;
|
||||||
|
button->text.FrontPen = draw_info->dri_Pens[TEXTPEN];
|
||||||
|
button->text.ITextFont = font;
|
||||||
|
button->text.IText = text;
|
||||||
|
button->gadget.Width = IntuiTextLength(&button->text) + 2 *
|
||||||
|
button->text.LeftEdge;
|
||||||
|
button->gadget.Height = font->ta_YSize + 2 * button->text.TopEdge;
|
||||||
|
SetAttrs(button->gadget.GadgetRender,
|
||||||
|
IA_Width, (LONG) button->gadget.Width,
|
||||||
|
IA_Height, (LONG) button->gadget.Height,
|
||||||
|
TAG_DONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void format_text(struct IntuiText *text, struct TextAttr *font,
|
||||||
|
struct DrawInfo *draw_info, int mar_x, int mar_y, int *width, int *height)
|
||||||
|
{
|
||||||
|
int pad_x = draw_info->dri_Font->tf_XSize * 2;
|
||||||
|
int pad_y = draw_info->dri_Font->tf_YSize * 3 / 4;
|
||||||
|
int x = pad_x + mar_x;
|
||||||
|
int y = pad_y + mar_y;
|
||||||
|
int line_h = font->ta_YSize + LINE_SPACING;
|
||||||
|
|
||||||
|
*width = 0, *height = 0;
|
||||||
|
for ( ; text != NULL; text = text->NextText) {
|
||||||
|
text->FrontPen = draw_info->dri_Pens[TEXTPEN];
|
||||||
|
text->DrawMode = JAM1;
|
||||||
|
text->LeftEdge = x;
|
||||||
|
text->TopEdge = y;
|
||||||
|
text->ITextFont = font;
|
||||||
|
y += line_h;
|
||||||
|
*width = max(IntuiTextLength(text), *width);
|
||||||
|
*height += line_h;
|
||||||
|
}
|
||||||
|
*width += 2 * pad_x;
|
||||||
|
*height += 2 * pad_y - LINE_SPACING;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dispose_images(struct Image *img)
|
||||||
|
{
|
||||||
|
struct Image *next;
|
||||||
|
|
||||||
|
while (img != NULL) {
|
||||||
|
next = img->NextImage;
|
||||||
|
DisposeObject(img);
|
||||||
|
img = next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int message_cons(Message *msg)
|
||||||
|
{
|
||||||
|
static USHORT dither[] = { 0x5555, 0xAAAA };
|
||||||
|
struct Image *background, *outer_frame, *inner_frame;
|
||||||
|
|
||||||
|
InitRequester(&msg->requester);
|
||||||
|
msg->requester.ReqGadget = &msg->button.gadget;
|
||||||
|
msg->requester.Flags = USEREQIMAGE | SIMPLEREQ;
|
||||||
|
if ((background = NewObject(NULL, "fillrectclass",
|
||||||
|
IA_APattern, dither,
|
||||||
|
IA_APatSize, 1L,
|
||||||
|
TAG_DONE)) == NULL)
|
||||||
|
goto message_cons_failed;
|
||||||
|
msg->requester.ReqImage = background;
|
||||||
|
if ((outer_frame = NewObject(NULL, "frameiclass",
|
||||||
|
IA_EdgesOnly, (ULONG) TRUE,
|
||||||
|
TAG_DONE)) == NULL)
|
||||||
|
goto message_cons_failed;
|
||||||
|
background->NextImage = outer_frame;
|
||||||
|
if ((inner_frame = NewObject(NULL, "frameiclass",
|
||||||
|
IA_Recessed, (ULONG) TRUE,
|
||||||
|
TAG_DONE)) == NULL)
|
||||||
|
goto message_cons_failed;
|
||||||
|
outer_frame->NextImage = inner_frame;
|
||||||
|
if (!button_cons(&msg->button))
|
||||||
|
goto message_cons_failed;
|
||||||
|
msg->button.gadget.NextGadget = NULL;
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
message_cons_failed:
|
||||||
|
dispose_images(msg->requester.ReqImage);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void message_layout(Message *msg, struct Window *window,
|
||||||
|
struct DrawInfo *draw_info, struct IntuiText *text, UBYTE *button_text)
|
||||||
|
{
|
||||||
|
struct Image *background = msg->requester.ReqImage;
|
||||||
|
struct Image *outer_frame = background->NextImage;
|
||||||
|
struct Image *inner_frame = outer_frame->NextImage;
|
||||||
|
struct TextAttr *font = window->WScreen->Font;
|
||||||
|
int pad_x = draw_info->dri_Font->tf_XSize;
|
||||||
|
int pad_y = draw_info->dri_Font->tf_YSize / 2;
|
||||||
|
int text_w, text_h;
|
||||||
|
|
||||||
|
msg->requester.ReqText = text;
|
||||||
|
button_layout(&msg->button, font, draw_info, button_text);
|
||||||
|
format_text(text, font, draw_info, pad_x, pad_y, &text_w, &text_h);
|
||||||
|
msg->requester.Width = 2 * pad_x + text_w;
|
||||||
|
msg->requester.Height = 3*pad_y - 1 + text_h + msg->button.gadget.Height;
|
||||||
|
msg->button.gadget.LeftEdge = (msg->requester.Width -
|
||||||
|
msg->button.gadget.Width) / 2;
|
||||||
|
msg->button.gadget.TopEdge = msg->requester.Height -
|
||||||
|
msg->button.gadget.Height - pad_y;
|
||||||
|
msg->requester.LeftEdge = max(0, window->BorderLeft + (window->Width -
|
||||||
|
window->BorderLeft - window->BorderRight - msg->requester.Width) / 2);
|
||||||
|
msg->requester.TopEdge = max(0, window->BorderTop + (window->Height -
|
||||||
|
window->BorderTop - window->BorderBottom - msg->requester.Height) / 2);
|
||||||
|
SetAttrs(inner_frame,
|
||||||
|
IA_Left, (LONG) pad_x,
|
||||||
|
IA_Top, (LONG) pad_y,
|
||||||
|
IA_Width, (LONG) text_w,
|
||||||
|
IA_Height, (LONG) text_h,
|
||||||
|
TAG_DONE);
|
||||||
|
SetAttrs(outer_frame,
|
||||||
|
IA_Width, (LONG) msg->requester.Width,
|
||||||
|
IA_Height, (LONG) msg->requester.Height,
|
||||||
|
TAG_DONE);
|
||||||
|
SetAttrs(background,
|
||||||
|
IA_Width, (LONG) msg->requester.Width,
|
||||||
|
IA_Height, (LONG) msg->requester.Height,
|
||||||
|
IA_FGPen, (ULONG) draw_info->dri_Pens[SHINEPEN],
|
||||||
|
TAG_DONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void message_dest(Message *msg)
|
||||||
|
{
|
||||||
|
button_dest(&msg->button);
|
||||||
|
dispose_images(msg->requester.ReqImage);
|
||||||
|
}
|
|
@ -0,0 +1,43 @@
|
||||||
|
/*
|
||||||
|
ToolsMenu - Add tools to the Workbench Tools menu
|
||||||
|
|
||||||
|
Copyright (C) 2015, 2018 Kim Fastrup Larsen
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation, either ver-
|
||||||
|
sion 3 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be use-
|
||||||
|
ful, but WITHOUT ANY WARRANTY; without even the implied war-
|
||||||
|
ranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
See the GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public Li-
|
||||||
|
cense along with this program. If not, see
|
||||||
|
<http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
The author can be contacted on <kimflarsen@hotmail.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MESSAGE_H
|
||||||
|
#define MESSAGE_H
|
||||||
|
|
||||||
|
#include <intuition/intuition.h>
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
struct Gadget gadget;
|
||||||
|
struct IntuiText text;
|
||||||
|
} Button;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
struct Requester requester;
|
||||||
|
Button button;
|
||||||
|
} Message;
|
||||||
|
|
||||||
|
int message_cons(Message *);
|
||||||
|
void message_layout(Message *, struct Window *, struct DrawInfo *,
|
||||||
|
struct IntuiText *text, UBYTE *button_text);
|
||||||
|
void message_dest(Message *);
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,56 @@
|
||||||
|
LIB = LIB:scs.lib LIB:amiga.lib
|
||||||
|
LINK = slink
|
||||||
|
LINKOPT = SMALLCODE SMALLDATA DEFINE @__chkabort=@__dummy DEFINE @_CXBRK=@__dummy QUIET
|
||||||
|
|
||||||
|
STARTUP = LIB:c.o
|
||||||
|
|
||||||
|
NAME = ToolsMenu
|
||||||
|
NAMELC = toolsmenu
|
||||||
|
OBJ = args.o broker.o catalog.o common.o cx.o error.o gui.o io.o main.o message.o sprintf.o toolrun.o wb.o
|
||||||
|
DANSKCAT = Catalogs/dansk/$(NAMELC).catalog
|
||||||
|
|
||||||
|
all: $(NAME) $(NAME).info empty.ct $(DANSKCAT)
|
||||||
|
@Echo "*nBuild succeeded."
|
||||||
|
|
||||||
|
clean:
|
||||||
|
-Delete >NIL: \#?.o $(NAME) $(NAME).info empty.ct $(DANSKCAT)
|
||||||
|
-Delete >NIL: Catalogs/dansk
|
||||||
|
-Delete >NIL: Catalogs
|
||||||
|
|
||||||
|
$(NAME): $(OBJ)
|
||||||
|
$(LINK) FROM $(STARTUP) $(OBJ) TO $@ LIB $(LIB) $(LINKOPT)
|
||||||
|
|
||||||
|
$(NAME).info:
|
||||||
|
@Copy Resources/$(NAME).info ""
|
||||||
|
|
||||||
|
.asm.o:
|
||||||
|
GenAm FROM $< TO $@ ALINK QUIET
|
||||||
|
|
||||||
|
args.o: args.c args.h common.h
|
||||||
|
broker.o: broker.c broker.h args.h catalog.h common.h cx.h error.h strings.h
|
||||||
|
catalog.o: catalog.c catalog.h strings.h
|
||||||
|
common.o: common.c common.h
|
||||||
|
cx.o: cx.c cx.h args.h common.h gui.h io.h wb.h
|
||||||
|
error.o: error.c error.h catalog.h common.h strings.h
|
||||||
|
gui.o: gui.c gui.h args.h catalog.h common.h compiler.h cx.h message.h strings.h wb.h
|
||||||
|
io.o: io.c io.h common.h cx.h
|
||||||
|
main.o: main.c args.h broker.h catalog.h common.h cx.h error.h gui.h strings.h toolrun.h wb.h
|
||||||
|
message.o: message.c message.h
|
||||||
|
sprintf.o: sprintf.asm
|
||||||
|
toolrun.o: toolrun.c toolrun.h common.h
|
||||||
|
wb.o: wb.c wb.h common.h cx.h toolrun.h
|
||||||
|
|
||||||
|
strings.h: $(NAMELC).cd
|
||||||
|
CatComp $(NAMELC).cd CFILE strings.h
|
||||||
|
|
||||||
|
empty.ct: $(NAMELC).cd
|
||||||
|
CatComp $(NAMELC).cd CTFILE empty.ct
|
||||||
|
|
||||||
|
$(DANSKCAT): $(NAMELC).cd dansk.ct Catalogs/dansk
|
||||||
|
CatComp $(NAMELC).cd dansk.ct CATALOG $(DANSKCAT)
|
||||||
|
|
||||||
|
Catalogs/dansk: Catalogs
|
||||||
|
@MakeDir Catalogs/dansk
|
||||||
|
|
||||||
|
Catalogs:
|
||||||
|
@MakeDir Catalogs
|
|
@ -0,0 +1,45 @@
|
||||||
|
; ToolsMenu - Add tools to the Workbench Tools menu
|
||||||
|
;
|
||||||
|
; Copyright (C) 2015, 2018 Kim Fastrup Larsen
|
||||||
|
;
|
||||||
|
; This program is free software: you can redistribute it and/or
|
||||||
|
; modify it under the terms of the GNU General Public License
|
||||||
|
; as published by the Free Software Foundation, either ver-
|
||||||
|
; sion 3 of the License, or (at your option) any later version.
|
||||||
|
;
|
||||||
|
; This program is distributed in the hope that it will be use-
|
||||||
|
; ful, but WITHOUT ANY WARRANTY; without even the implied war-
|
||||||
|
; ranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
; See the GNU General Public License for more details.
|
||||||
|
;
|
||||||
|
; You should have received a copy of the GNU General Public Li-
|
||||||
|
; cense along with this program. If not, see
|
||||||
|
; <http://www.gnu.org/licenses/>.
|
||||||
|
;
|
||||||
|
; The author can be contacted on <kimflarsen@hotmail.com>
|
||||||
|
;
|
||||||
|
; Simple version of the C "sprintf" function. Assumes C-style
|
||||||
|
; stack-based function conventions.
|
||||||
|
|
||||||
|
XDEF _sprintf
|
||||||
|
|
||||||
|
XREF _AbsExecBase
|
||||||
|
XREF _LVORawDoFmt
|
||||||
|
|
||||||
|
_sprintf:
|
||||||
|
movem.l a2/a3/a6,-(sp)
|
||||||
|
|
||||||
|
move.l 4*4(sp),a3 ; Get the output string pointer
|
||||||
|
move.l 5*4(sp),a0 ; Get the FormatString pointer
|
||||||
|
lea.l 6*4(sp),a1 ; Get the pointer to the DataStream
|
||||||
|
lea.l stuffChar(pc),a2
|
||||||
|
move.l _AbsExecBase,a6
|
||||||
|
jsr _LVORawDoFmt(a6)
|
||||||
|
|
||||||
|
movem.l (sp)+,a2/a3/a6
|
||||||
|
rts
|
||||||
|
|
||||||
|
; PutChProc used by RawDoFmt
|
||||||
|
stuffChar:
|
||||||
|
move.b d0,(a3)+
|
||||||
|
rts
|
|
@ -0,0 +1,183 @@
|
||||||
|
/*
|
||||||
|
ToolsMenu - Add tools to the Workbench Tools menu
|
||||||
|
|
||||||
|
Copyright (C) 2015, 2018 Kim Fastrup Larsen
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation, either ver-
|
||||||
|
sion 3 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be use-
|
||||||
|
ful, but WITHOUT ANY WARRANTY; without even the implied war-
|
||||||
|
ranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
See the GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public Li-
|
||||||
|
cense along with this program. If not, see
|
||||||
|
<http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
The author can be contacted on <kimflarsen@hotmail.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <dos/dos.h>
|
||||||
|
#include <dos/dostags.h>
|
||||||
|
#include <exec/memory.h>
|
||||||
|
#include <workbench/startup.h>
|
||||||
|
|
||||||
|
#include <clib/dos_protos.h>
|
||||||
|
#include <clib/exec_protos.h>
|
||||||
|
#include <clib/icon_protos.h>
|
||||||
|
|
||||||
|
#ifdef USE_PRAGMAS
|
||||||
|
#include <proto/dos.h>
|
||||||
|
#include <proto/exec.h>
|
||||||
|
#include <proto/icon.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
#include "toolrun.h"
|
||||||
|
|
||||||
|
#define MIN_STACK_SIZE 4000
|
||||||
|
|
||||||
|
/* We send this extended WBStartup to any tool that we launch. It will
|
||||||
|
contain the Workbench arguments passed to run_tool(). Once the tool quits,
|
||||||
|
it will reply to this message, and at that point we call the clean_up
|
||||||
|
function (also passed to run_tool()) to let it clean up the arguments. */
|
||||||
|
typedef struct {
|
||||||
|
struct WBStartup wb_startup;
|
||||||
|
Tr_clean_up *clean_up;
|
||||||
|
void *user_data;
|
||||||
|
} Startmsg;
|
||||||
|
|
||||||
|
/* The tools we run will be told to reply to this port when they quit. */
|
||||||
|
static struct MsgPort *reply_port;
|
||||||
|
/* The number of tools started that haven't quit yet. */
|
||||||
|
static int running;
|
||||||
|
|
||||||
|
static void free_startmsg(Startmsg *msg)
|
||||||
|
{
|
||||||
|
FreeVec(msg->wb_startup.sm_ToolWindow);
|
||||||
|
FreeMem(msg, sizeof *msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create the reply port and return its signal bit as a mask. */
|
||||||
|
ULONG tr_set_up()
|
||||||
|
{
|
||||||
|
if ((reply_port = CreateMsgPort()) == NULL)
|
||||||
|
exit(RETURN_FAIL);
|
||||||
|
return 1UL << reply_port->mp_SigBit;
|
||||||
|
}
|
||||||
|
|
||||||
|
Bool tr_run_tool(struct WBArg *arg_list, LONG num_args,
|
||||||
|
Tr_clean_up *clean_up, void *user_data)
|
||||||
|
{
|
||||||
|
BPTR old_dir;
|
||||||
|
struct DiskObject *disk_obj;
|
||||||
|
Startmsg *startmsg;
|
||||||
|
LONG stack_size;
|
||||||
|
BPTR home_dir;
|
||||||
|
struct Process *process;
|
||||||
|
|
||||||
|
/* Load the tool's icon and check that it really is a Workbench tool. */
|
||||||
|
old_dir = CurrentDir(arg_list[0].wa_Lock);
|
||||||
|
if ((disk_obj = GetDiskObject(arg_list[0].wa_Name)) == NULL)
|
||||||
|
goto run_tool_failed1;
|
||||||
|
if (disk_obj->do_Type != WBTOOL)
|
||||||
|
goto run_tool_failed2;
|
||||||
|
/* Use the stacksize specified in the icon unless it's too small. */
|
||||||
|
if ((stack_size = disk_obj->do_StackSize) < MIN_STACK_SIZE)
|
||||||
|
stack_size = MIN_STACK_SIZE;
|
||||||
|
/* Set up startup message. */
|
||||||
|
if ((startmsg=AllocMem(sizeof *startmsg,MEMF_PUBLIC|MEMF_CLEAR)) == NULL)
|
||||||
|
goto run_tool_failed2;
|
||||||
|
startmsg->wb_startup.sm_ArgList = arg_list;
|
||||||
|
startmsg->wb_startup.sm_NumArgs = num_args;
|
||||||
|
startmsg->clean_up = clean_up;
|
||||||
|
startmsg->user_data = user_data;
|
||||||
|
/* We copy the icon's ToolWindow if it isn't NULL. */
|
||||||
|
if (disk_obj->do_ToolWindow != NULL &&
|
||||||
|
(startmsg->wb_startup.sm_ToolWindow = copy_of(disk_obj->do_ToolWindow))
|
||||||
|
== NULL)
|
||||||
|
goto run_tool_failed3;
|
||||||
|
/* Load the tool. */
|
||||||
|
if ((startmsg->wb_startup.sm_Segment = NewLoadSegTags(
|
||||||
|
arg_list[0].wa_Name, TAG_DONE)) == NULL)
|
||||||
|
goto run_tool_failed3;
|
||||||
|
/* Get a lock for PROGDIR. */
|
||||||
|
if ((home_dir = DupLock(arg_list[0].wa_Lock)) == 0)
|
||||||
|
goto run_tool_failed4;
|
||||||
|
/* Run the tool as a non-CLI process. */
|
||||||
|
if ((process = CreateNewProcTags(
|
||||||
|
NP_Seglist, startmsg->wb_startup.sm_Segment,
|
||||||
|
NP_FreeSeglist, (LONG) TRUE,
|
||||||
|
NP_Input, NULL,
|
||||||
|
NP_CloseInput, (LONG) FALSE,
|
||||||
|
NP_Output, NULL,
|
||||||
|
NP_CloseOutput, (LONG) FALSE,
|
||||||
|
NP_Error, NULL,
|
||||||
|
NP_CloseError, (LONG) FALSE,
|
||||||
|
NP_CurrentDir, NULL,
|
||||||
|
NP_StackSize, stack_size,
|
||||||
|
NP_Name, arg_list[0].wa_Name,
|
||||||
|
NP_Priority, 0L,
|
||||||
|
NP_ConsoleTask, NULL,
|
||||||
|
NP_WindowPtr, NULL,
|
||||||
|
NP_HomeDir, home_dir,
|
||||||
|
TAG_DONE)) == NULL)
|
||||||
|
goto run_tool_failed5;
|
||||||
|
/* We have started the process, so we mustn't do anything after this point
|
||||||
|
that might fail. Send the startup message to the tool. */
|
||||||
|
startmsg->wb_startup.sm_Process = &process->pr_MsgPort;
|
||||||
|
startmsg->wb_startup.sm_Message.mn_ReplyPort = reply_port;
|
||||||
|
PutMsg(startmsg->wb_startup.sm_Process, (struct Message *) startmsg);
|
||||||
|
++running;
|
||||||
|
FreeDiskObject(disk_obj);
|
||||||
|
CurrentDir(old_dir);
|
||||||
|
return YES;
|
||||||
|
|
||||||
|
run_tool_failed5:
|
||||||
|
UnLock(home_dir);
|
||||||
|
|
||||||
|
run_tool_failed4:
|
||||||
|
UnLoadSeg(startmsg->wb_startup.sm_Segment);
|
||||||
|
|
||||||
|
run_tool_failed3:
|
||||||
|
free_startmsg(startmsg);
|
||||||
|
|
||||||
|
run_tool_failed2:
|
||||||
|
FreeDiskObject(disk_obj);
|
||||||
|
|
||||||
|
run_tool_failed1:
|
||||||
|
CurrentDir(old_dir);
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* When a tool started by tr_run_tool() quits, we receive a reply to our
|
||||||
|
startup message. At this point we call the clean up function provided,
|
||||||
|
then clean up the message itself. */
|
||||||
|
void tr_handle_signal()
|
||||||
|
{
|
||||||
|
Startmsg *msg;
|
||||||
|
|
||||||
|
while ((msg = (Startmsg *) GetMsg(reply_port)) != NULL) {
|
||||||
|
(*msg->clean_up)(msg->wb_startup.sm_ArgList,
|
||||||
|
msg->wb_startup.sm_NumArgs, msg->user_data);
|
||||||
|
free_startmsg(msg);
|
||||||
|
--running;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Wait for all currently running tools to quit before cleaning up the
|
||||||
|
reply port and returning control to the caller. */
|
||||||
|
void tr_clean_up()
|
||||||
|
{
|
||||||
|
while (running > 0 ) {
|
||||||
|
WaitPort(reply_port);
|
||||||
|
tr_handle_signal();
|
||||||
|
}
|
||||||
|
DeleteMsgPort(reply_port);
|
||||||
|
}
|
|
@ -0,0 +1,60 @@
|
||||||
|
/*
|
||||||
|
ToolsMenu - Add tools to the Workbench Tools menu
|
||||||
|
|
||||||
|
Copyright (C) 2015, 2018 Kim Fastrup Larsen
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation, either ver-
|
||||||
|
sion 3 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be use-
|
||||||
|
ful, but WITHOUT ANY WARRANTY; without even the implied war-
|
||||||
|
ranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
See the GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public Li-
|
||||||
|
cense along with this program. If not, see
|
||||||
|
<http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
The author can be contacted on <kimflarsen@hotmail.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef TOOLRUN_H
|
||||||
|
#define TOOLRUN_H
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
|
/* The signature of the function that will be called when a tool quits (see
|
||||||
|
below). */
|
||||||
|
typedef void Tr_clean_up(struct WBArg *, LONG num_args, void *user_data);
|
||||||
|
|
||||||
|
/* This function must be called once as part of program initialization. Do
|
||||||
|
not call tr_run_tool() before calling this function. It sets up a message
|
||||||
|
port, for which the signal bit will be returned as a mask. Whenever you
|
||||||
|
receive this signal, call tr_handle_signal() to deal with it. */
|
||||||
|
ULONG tr_set_up(void);
|
||||||
|
|
||||||
|
/* Run a tool as if started from Workbench.
|
||||||
|
arg_list: An array of WBArg structures. The first element must
|
||||||
|
represent the tool to run, and the rest are its arguments.
|
||||||
|
num_args: The number of elements in arg_list.
|
||||||
|
clean_up: A pointer to a function that will be called when the tool
|
||||||
|
quits - it will be called from within tr_handle_signal() or
|
||||||
|
tr_clean_up(). arg_list, num_args and user_data will be passed
|
||||||
|
to clean_up.
|
||||||
|
user_data: This can be anything. It will be passed to clean_up. */
|
||||||
|
Bool tr_run_tool(struct WBArg *arg_list, LONG num_args,
|
||||||
|
Tr_clean_up *clean_up, void *user_data);
|
||||||
|
|
||||||
|
/* You must call this function whenever you receive the signal returned by
|
||||||
|
tr_set_up(). */
|
||||||
|
void tr_handle_signal(void);
|
||||||
|
|
||||||
|
/* You must call this once before quitting. Do not call tr_run_tool() after
|
||||||
|
calling this function.
|
||||||
|
NB: This function will wait around for all tools started by tr_run_tool()
|
||||||
|
to quit before returning. */
|
||||||
|
void tr_clean_up(void);
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,71 @@
|
||||||
|
; ToolsMenu - Add tools to the Workbench Tools menu
|
||||||
|
;
|
||||||
|
; Copyright (C) 2015, 2018 Kim Fastrup Larsen
|
||||||
|
;
|
||||||
|
; This program is free software: you can redistribute it and/or
|
||||||
|
; modify it under the terms of the GNU General Public License
|
||||||
|
; as published by the Free Software Foundation, either ver-
|
||||||
|
; sion 3 of the License, or (at your option) any later version.
|
||||||
|
;
|
||||||
|
; This program is distributed in the hope that it will be use-
|
||||||
|
; ful, but WITHOUT ANY WARRANTY; without even the implied war-
|
||||||
|
; ranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
; See the GNU General Public License for more details.
|
||||||
|
;
|
||||||
|
; You should have received a copy of the GNU General Public Li-
|
||||||
|
; cense along with this program. If not, see
|
||||||
|
; <http://www.gnu.org/licenses/>.
|
||||||
|
;
|
||||||
|
; The author can be contacted on <kimflarsen@hotmail.com>
|
||||||
|
;
|
||||||
|
MSG_ERR_OPEN (//)
|
||||||
|
Could not open %s
|
||||||
|
;
|
||||||
|
MSG_ERR_HOTKEY (//)
|
||||||
|
Illegal hot key
|
||||||
|
;
|
||||||
|
MSG_WINDOW_TITLE (//)
|
||||||
|
%s: Hot Key = <%s>
|
||||||
|
;
|
||||||
|
MSG_DESCRIPTION (//)
|
||||||
|
Add tools to the Workbench Tools Menu
|
||||||
|
; Description should be at most 40 characters
|
||||||
|
MSG_PROJECT_MENU (//)
|
||||||
|
Project
|
||||||
|
;
|
||||||
|
MSG_PROJECT_SAVE (//)
|
||||||
|
Save Menu Items
|
||||||
|
;
|
||||||
|
MSG_PROJECT_HIDE (//)
|
||||||
|
Hide
|
||||||
|
;
|
||||||
|
MSG_PROJECT_ABOUT (//)
|
||||||
|
About...
|
||||||
|
;
|
||||||
|
MSG_PROJECT_QUIT (//)
|
||||||
|
Quit
|
||||||
|
;
|
||||||
|
MSG_GAD_CONTINUE (//)
|
||||||
|
Continue
|
||||||
|
;
|
||||||
|
MSG_GAD_MENU_ITEMS (//)
|
||||||
|
Menu Items
|
||||||
|
;
|
||||||
|
MSG_GAD_NEW (//)
|
||||||
|
New
|
||||||
|
;
|
||||||
|
MSG_GAD_DELETE (//)
|
||||||
|
Delete
|
||||||
|
;
|
||||||
|
MSG_GAD_TOOL (//)
|
||||||
|
Tool
|
||||||
|
;
|
||||||
|
MSG_INFO_1 (//)
|
||||||
|
You can add tools
|
||||||
|
;
|
||||||
|
MSG_INFO_2 (//)
|
||||||
|
by dragging their icons
|
||||||
|
;
|
||||||
|
MSG_INFO_3 (//)
|
||||||
|
into this window.
|
||||||
|
;
|
|
@ -0,0 +1,209 @@
|
||||||
|
/*
|
||||||
|
ToolsMenu - Add tools to the Workbench Tools menu
|
||||||
|
|
||||||
|
Copyright (C) 2015, 2018 Kim Fastrup Larsen
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation, either ver-
|
||||||
|
sion 3 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be use-
|
||||||
|
ful, but WITHOUT ANY WARRANTY; without even the implied war-
|
||||||
|
ranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
See the GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public Li-
|
||||||
|
cense along with this program. If not, see
|
||||||
|
<http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
The author can be contacted on <kimflarsen@hotmail.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <dos/dos.h>
|
||||||
|
#include <exec/memory.h>
|
||||||
|
#include <workbench/startup.h>
|
||||||
|
#include <workbench/workbench.h>
|
||||||
|
|
||||||
|
#include <clib/dos_protos.h>
|
||||||
|
#include <clib/exec_protos.h>
|
||||||
|
#include <clib/icon_protos.h>
|
||||||
|
#include <clib/wb_protos.h>
|
||||||
|
|
||||||
|
#ifdef USE_PRAGMAS
|
||||||
|
#include <proto/dos.h>
|
||||||
|
#include <proto/exec.h>
|
||||||
|
#include <proto/icon.h>
|
||||||
|
#include <proto/wb.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <strings.h>
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
#include "cx.h"
|
||||||
|
#include "toolrun.h"
|
||||||
|
#include "wb.h"
|
||||||
|
|
||||||
|
static struct MsgPort *wb_port;
|
||||||
|
|
||||||
|
static void add_tool_from_icon(char *name)
|
||||||
|
{
|
||||||
|
char path[MAX_PATH_LENGTH + 1];
|
||||||
|
BPTR lock;
|
||||||
|
|
||||||
|
if ((lock = Lock(name, ACCESS_READ)) == NULL)
|
||||||
|
return;
|
||||||
|
if (NameFromLock(lock, path, MAX_PATH_LENGTH + 1))
|
||||||
|
cx_add_tool(name, path);
|
||||||
|
UnLock(lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void handle_app_window_msg(struct AppMessage *msg)
|
||||||
|
{
|
||||||
|
struct WBArg *arg;
|
||||||
|
struct WBArg *end = msg->am_ArgList + msg->am_NumArgs;
|
||||||
|
BPTR old_dir;
|
||||||
|
struct DiskObject *disk_obj;
|
||||||
|
|
||||||
|
cx_show();
|
||||||
|
for (arg = msg->am_ArgList; arg != end; ++arg) {
|
||||||
|
old_dir = CurrentDir(arg->wa_Lock);
|
||||||
|
/* Check that name isn't NULL and isn't empty, and that the icon is
|
||||||
|
a Workbench tool. */
|
||||||
|
if (arg->wa_Name != NULL && *arg->wa_Name != '\0')
|
||||||
|
if ((disk_obj = GetDiskObject(arg->wa_Name)) != NULL) {
|
||||||
|
if (disk_obj->do_Type == WBTOOL)
|
||||||
|
add_tool_from_icon(arg->wa_Name);
|
||||||
|
FreeDiskObject(disk_obj);
|
||||||
|
}
|
||||||
|
CurrentDir(old_dir);
|
||||||
|
}
|
||||||
|
ReplyMsg((struct Message *) msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void free_args(struct WBArg *arg_list, LONG num_args)
|
||||||
|
{
|
||||||
|
FreeVec(arg_list[0].wa_Name);
|
||||||
|
if (arg_list[0].wa_Lock != NULL)
|
||||||
|
UnLock(arg_list[0].wa_Lock);
|
||||||
|
FreeMem(arg_list, sizeof(struct WBArg) * num_args);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Creates the directory locks and tool names to pass to tr_run_tool(). It
|
||||||
|
actually only creates the first element, ie. the home directory and name
|
||||||
|
of the tool itself, the rest are copied from the AppMessage that
|
||||||
|
workbench.library sent us. */
|
||||||
|
static struct WBArg *create_args(STRPTR path, struct WBArg *arg_list,
|
||||||
|
LONG num_args)
|
||||||
|
{
|
||||||
|
struct WBArg *result;
|
||||||
|
size_t args_size;
|
||||||
|
UBYTE t;
|
||||||
|
UBYTE *file_part;
|
||||||
|
|
||||||
|
/* Create an array one element bigger than the one received from
|
||||||
|
workbench.library, so we can put the tool itself at the front. */
|
||||||
|
args_size = sizeof(struct WBArg) * num_args;
|
||||||
|
result = AllocMem(args_size+sizeof(struct WBArg),MEMF_PUBLIC|MEMF_CLEAR);
|
||||||
|
if (result == NULL)
|
||||||
|
return NULL;
|
||||||
|
/* Temporarily separate the file part and directory part of the tool's
|
||||||
|
path with a string terminator. */
|
||||||
|
t = *(file_part = FilePart(path));
|
||||||
|
*file_part = '\0';
|
||||||
|
/* Create the tool's directory lock. */
|
||||||
|
result[0].wa_Lock = Lock(path, ACCESS_READ);
|
||||||
|
/* Restore original string. */
|
||||||
|
*file_part = t;
|
||||||
|
if (result[0].wa_Lock == NULL)
|
||||||
|
goto create_args_failed;
|
||||||
|
/* Copy the tool's name. */
|
||||||
|
if ((result[0].wa_Name = copy_of(file_part)) == NULL)
|
||||||
|
goto create_args_failed;
|
||||||
|
/* The rest of the array is just a copy of the AppMessage array. */
|
||||||
|
if (args_size > 0)
|
||||||
|
memcpy(result + 1, arg_list, args_size);
|
||||||
|
return result;
|
||||||
|
|
||||||
|
create_args_failed:
|
||||||
|
free_args(result, num_args + 1);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
/* This function is called whenever a tool we started quits. At this point,
|
||||||
|
we reply to the workbench.library so it can free the arguments that we
|
||||||
|
borrowed. Called indirectly by tr_clean_up(), so we must not clean up
|
||||||
|
anything needed by reply_app_msg() until after the call to tr_clean_up().
|
||||||
|
*/
|
||||||
|
static void reply_app_msg(struct WBArg *arg_list, LONG num_args,
|
||||||
|
struct AppMessage *app_message)
|
||||||
|
{
|
||||||
|
if (arg_list != NULL)
|
||||||
|
free_args(arg_list, num_args);
|
||||||
|
ReplyMsg((struct Message *) app_message);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void handle_app_menu_item_msg(struct AppMessage *msg)
|
||||||
|
{
|
||||||
|
Tool *t = (Tool *) msg->am_UserData;
|
||||||
|
struct WBArg *args = NULL;
|
||||||
|
LONG num_args = msg->am_NumArgs + 1;
|
||||||
|
|
||||||
|
/* Check that the path isn't empty and that the tool hasn't been removed
|
||||||
|
prior to handling this event, then create the Workbench arguments and
|
||||||
|
run the tool. */
|
||||||
|
if (*t->path == '\0' || !is_in_list(tools, &t->node) ||
|
||||||
|
(args = create_args(t->path,msg->am_ArgList,msg->am_NumArgs)) == NULL ||
|
||||||
|
!tr_run_tool(args, num_args, reply_app_msg, msg))
|
||||||
|
/* Failed to run, reply to the AppMessage right away. */
|
||||||
|
reply_app_msg(args, num_args, msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
ULONG wb_set_up()
|
||||||
|
{
|
||||||
|
if ((wb_port = CreateMsgPort()) == NULL)
|
||||||
|
exit(RETURN_FAIL);
|
||||||
|
return 1UL << wb_port->mp_SigBit;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct AppWindow *wb_add_window(struct Window *window)
|
||||||
|
{
|
||||||
|
return AddAppWindow(0, 0, window, wb_port, TAG_DONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void wb_remove_window(struct AppWindow *app_window)
|
||||||
|
{
|
||||||
|
RemoveAppWindow(app_window);
|
||||||
|
}
|
||||||
|
|
||||||
|
void wb_add_tool(Tool *tool)
|
||||||
|
{
|
||||||
|
tool->menu_item = AddAppMenuItemA(0, (ULONG) tool, tool->node.ln_Name,
|
||||||
|
wb_port, TAG_DONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void wb_remove_tool(Tool *tool)
|
||||||
|
{
|
||||||
|
RemoveAppMenuItem(tool->menu_item);
|
||||||
|
tool->menu_item = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void wb_handle_signal(void)
|
||||||
|
{
|
||||||
|
struct AppMessage *msg;
|
||||||
|
|
||||||
|
while ((msg = (struct AppMessage *) GetMsg(wb_port)) != NULL)
|
||||||
|
switch (msg->am_Type) {
|
||||||
|
case AMTYPE_APPWINDOW:
|
||||||
|
handle_app_window_msg(msg);
|
||||||
|
break;
|
||||||
|
case AMTYPE_APPMENUITEM:
|
||||||
|
handle_app_menu_item_msg(msg);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void wb_clean_up()
|
||||||
|
{
|
||||||
|
delete_port(wb_port);
|
||||||
|
}
|
|
@ -0,0 +1,38 @@
|
||||||
|
/*
|
||||||
|
ToolsMenu - Add tools to the Workbench Tools menu
|
||||||
|
|
||||||
|
Copyright (C) 2015, 2018 Kim Fastrup Larsen
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation, either ver-
|
||||||
|
sion 3 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be use-
|
||||||
|
ful, but WITHOUT ANY WARRANTY; without even the implied war-
|
||||||
|
ranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
See the GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public Li-
|
||||||
|
cense along with this program. If not, see
|
||||||
|
<http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
The author can be contacted on <kimflarsen@hotmail.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef WB_H
|
||||||
|
#define WB_H
|
||||||
|
|
||||||
|
#include <exec/types.h>
|
||||||
|
|
||||||
|
#include "cx.h"
|
||||||
|
|
||||||
|
ULONG wb_set_up(void);
|
||||||
|
struct AppWindow *wb_add_window(struct Window *);
|
||||||
|
void wb_remove_window(struct AppWindow *);
|
||||||
|
void wb_add_tool(Tool *);
|
||||||
|
void wb_remove_tool(Tool *);
|
||||||
|
void wb_handle_signal(void);
|
||||||
|
void wb_clean_up(void);
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in New Issue