Aros/开发者/文档/库/商品
随着 AmigaOS (TM) 2.0 的发布,商品被引入以扩展 Amiga Workbench(桌面)的功能。
商品库在直觉的处理程序之前设置了一个处理程序。当商品处理程序接收到 CxMessage 时
CxObjects 对 CxMessage 进行操作,以便它可以过滤某些 CxMessage、翻译 CxMessage、在 CxObject 接收到 CxMessage 时向任务发出信号、在 CxObject 接收到 CxMessage 时发送消息,或者在 CxObject 接收到 CxMessage 时调用自定义函数。
控制器程序称为 Exchange,非常适合需要监控所有用户输入的程序,例如热键、弹出窗口、屏幕保护程序和鼠标保护程序。
商品交换永远不应作为应用程序接收用户输入的替代方法。
看看 这里
默认情况下,每个 Zune 应用程序也是一个商品。MUI 也会为您完成此操作。查看 muimaster/classes/application.c 中启用的 MUIA_Application_UseCommodities 部分(第 625-660 行):它似乎只设置(或在为 FALSE 时避免)Zune 对您的工具作为商品的初始化,并且键盘快捷键有效。
在创建过滤器时,您应该创建代理、将过滤器附加到代理,然后是发送方。过滤器只接收您感兴趣的事件,而发送方通知代理。
FKey 商品使用过滤器
工具类型 «RAWMOUSE LBUTTON RBUTTON MOUSE_RIGHTPRESS» RUN App QUIET DONOTBUT CURRENT TOBACK
"RAWMOUSE MBUTTON MOUSE_MIDDLEPRESS"
/*
Copyright © 2012, The AROS Development Team. All rights reserved.
$Id$
ASCIITable -- Insert characters to clipboard from GUI.
*/
/******************************************************************************
NAME
ASCIITable
SYNOPSIS
CX_PRIORITY/N/K,CX_POPKEY/K,CX_POPUP/S
LOCATION
SYS:Tools/Commodities
FUNCTION
Insert characters to clipboard from GUI
INPUTS
CX_PRIORITY -- Priority of the ASCIITable broker
CX_POPKEY -- Hotkey combination for ASCIITable
CX_POPUP -- Appear at startup
RESULT
NOTES
EXAMPLE
BUGS
SEE ALSO
INTERNALS
******************************************************************************/
#define MUIMASTER_YES_INLINE_STDARG
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//#define DEBUG 1
#include <aros/debug.h>
#include <aros/asmcall.h>
#include <aros/symbolsets.h>
#include <libraries/iffparse.h>
#include <libraries/mui.h>
#include <zune/customclasses.h>
#include <devices/clipboard.h>
#include <workbench/startup.h>
#include <proto/muimaster.h>
#include <proto/locale.h>
#include <proto/intuition.h>
#include <proto/exec.h>
#include <proto/dos.h>
#include <proto/alib.h>
#include <proto/commodities.h>
#include <proto/utility.h>
#include <proto/icon.h>
#define CATCOMP_ARRAY
#include "strings.h"
#define CATALOG_NAME "System/Tools/Commodities.catalog"
#define CATALOG_VERSION 3
TEXT version[] = "$VER: ASCIITable 1.2 (14.01.2012)";
#define ARG_TEMPLATE "CX_PRIORITY/N/K,CX_POPKEY/K,CX_POPUP/S"
#define DEF_POPKEY "ctrl alt a"
enum {
ARG_CXPRI,
ARG_CXPOPKEY,
ARG_CXPOPUP,
NUM_ARGS
};
static Object *app, *wnd;
static struct Catalog *catalog;
static UBYTE s[257];
static struct Hook broker_hook;
static struct Hook show_hook;
static LONG cx_pri;
static char *cx_popkey;
static BOOL cx_popup = FALSE;
static CxObj *broker;
static struct MsgPort *brokermp;
static struct Task *maintask;
static void Cleanup(CONST_STRPTR txt);
static void GetArguments(int argc, char **argv);
static void HandleAll(void);
static void InitMenus(void);
static VOID Locale_Deinitialize(VOID);
static int Locale_Initialize(VOID);
static void MakeGUI(void);
static void showSimpleMessage(CONST_STRPTR msgString);
static CONST_STRPTR _(ULONG id);
static struct IOClipReq *CBOpen(ULONG unit);
static void CBClose(struct IOClipReq *ior);
static BOOL CBWriteFTXT(struct IOClipReq *ior, CONST_STRPTR string);
static BOOL CBWriteLong(struct IOClipReq *ior, LONG *ldata);
static struct DiskObject *disko;
/*** ASCIITable class *******************************************************/
#define MAXLEN (60)
#define ASCIITableObject BOOPSIOBJMACRO_START(ASCIITable_CLASS->mcc_Class)
#define MUIM_ASCIITable_Copy (TAG_USER | 1)
#define MUIM_ASCIITable_Clear (TAG_USER | 2)
#define MUIM_ASCIITable_Insert (TAG_USER | 3)
struct MUIP_ASCIITable_Insert {STACKED ULONG MethodID; STACKED LONG code;};
struct ASCIITable_DATA
{
Object *copy_button;
Object *clear_button;
Object *ascii_string;
TEXT buffer[MAXLEN + 1];
struct IOClipReq *clip_req;
TEXT shorthelp[192][20];
};
/*** CBOpen *****************************************************************/
static struct IOClipReq *CBOpen(ULONG unit)
{
struct MsgPort *mp;
struct IORequest *ior;
if ((mp = CreatePort(0, 0)))
{
if ((ior = (struct IORequest *)CreateExtIO(mp, sizeof(struct IOClipReq))))
{
if (!(OpenDevice("clipboard.device", unit, ior, 0)))
{
return (struct IOClipReq *)ior;
}
DeleteExtIO(ior);
}
DeletePort(mp);
}
return NULL;
}
/*** CBCLose ****************************************************************/
static void CBClose(struct IOClipReq *ior)
{
if (ior)
{
struct MsgPort *mp = ior->io_Message.mn_ReplyPort;
CloseDevice((struct IORequest *)ior);
DeleteExtIO((struct IORequest *)ior);
DeletePort(mp);
}
}
/*** CBWriteFTXT ************************************************************/
static BOOL CBWriteFTXT(struct IOClipReq *ior, CONST_STRPTR string)
{
LONG length, slen, temp;
BOOL odd;
if (!ior || !string)
return FALSE;
slen = strlen(string);
odd = (slen & 1);
length = (odd) ? slen+1 : slen;
ior->io_Offset = 0;
ior->io_Error = 0;
ior->io_ClipID = 0;
CBWriteLong(ior, (LONG *) "FORM");
length += 12;
temp = AROS_LONG2BE(length);
CBWriteLong(ior, &temp);
CBWriteLong(ior, (LONG *) "FTXT");
CBWriteLong(ior, (LONG *) "CHRS");
temp = AROS_LONG2BE(slen);
CBWriteLong(ior, &temp);
ior->io_Data = (STRPTR)string;
ior->io_Length = slen;
ior->io_Command = CMD_WRITE;
DoIO((struct IORequest *)ior);
if (odd)
{
ior->io_Data = (APTR)"";
ior->io_Length = 1;
DoIO((struct IORequest *)ior);
}
ior->io_Command=CMD_UPDATE;
DoIO ((struct IORequest *)ior);
return ior->io_Error ? FALSE : TRUE;
}
/*** WriteLong **************************************************************/
static BOOL CBWriteLong(struct IOClipReq *ior, LONG *ldata)
{
ior->io_Data = (APTR)ldata;
ior->io_Length = 4;
ior->io_Command = CMD_WRITE;
DoIO( (struct IORequest *) ior);
if (ior->io_Actual == 4)
{
return ior->io_Error ? FALSE : TRUE;
}
return FALSE;
}
/*** MakeButton *************************************************************/
static Object *MakeButton(LONG code)
{
char buffer[2] = {0};
buffer[0] = code;
Object *btn = (Object *)TextObject,
ButtonFrame,
MUIA_Font, MUIV_Font_Button,
MUIA_Text_Contents, (IPTR)buffer,
MUIA_Text_PreParse, (IPTR)"\33c",
MUIA_InputMode , MUIV_InputMode_RelVerify,
MUIA_Background , MUII_ButtonBack,
MUIA_CycleChain , TRUE,
End;
return btn;
}
/*** OM_NEW *****************************************************************/
IPTR ASCIITable__OM_NEW(Class *CLASS, Object *self, struct opSet *message)
{
struct ASCIITable_DATA *data = NULL;
Object *copy_button, *clear_button, *ascii_string, *key_group;
struct TagItem key_group_tags[200];
LONG i, code;
for (code = 32 , i = 0 ; code < 128 ; code++ , i++)
{
key_group_tags[i].ti_Tag = Child;
key_group_tags[i].ti_Data = (IPTR)MakeButton(code);
}
for (code = 160 ; code < 256 ; code++, i++)
{
key_group_tags[i].ti_Tag = Child;
key_group_tags[i].ti_Data = (IPTR)MakeButton(code);
}
key_group_tags[i].ti_Tag = MUIA_Group_Columns;
key_group_tags[i].ti_Data = 16;
key_group_tags[++i].ti_Tag = TAG_DONE;
key_group = MUI_NewObjectA(MUIC_Group, key_group_tags);
self = (Object *) DoSuperNewTags
(
CLASS, self, NULL,
Child, key_group,
Child, (IPTR) (RectangleObject,
MUIA_Rectangle_HBar, TRUE,
MUIA_FixHeight, 2,
End),
Child, (IPTR)(ascii_string = (Object *)StringObject,
StringFrame,
MUIA_String_MaxLen, MAXLEN,
End),
Child, (IPTR) (HGroup,
MUIA_Weight, 0,
MUIA_Group_SameSize, TRUE,
Child, (IPTR) (copy_button = SimpleButton(_(MSG_ASCIITABLE_GAD_COPY))),
Child, (IPTR) (clear_button = SimpleButton(_(MSG_ASCIITABLE_GAD_CLEAR))),
End),
TAG_MORE, message->ops_AttrList
);
if (self != NULL)
{
/*-- Store important variables -------------------------------------*/
data = INST_DATA(CLASS, self);
data->copy_button = copy_button;
data->clear_button = clear_button;
data->ascii_string = ascii_string;
/*-- Setup notifications -------------------------------------------*/
DoMethod
(
copy_button, MUIM_Notify, MUIA_Pressed, FALSE,
(IPTR) self, 1, MUIM_ASCIITable_Copy
);
DoMethod
(
clear_button, MUIM_Notify, MUIA_Pressed, FALSE,
(IPTR) self, 1, MUIM_ASCIITable_Clear
);
for (i = 0 ; i < 192 ; i++)
{
code = (i < 96) ? i + 32 : i + 64;
sprintf(data->shorthelp[i], "%c\n%d\n0x%x", (int)code, (int)code, (unsigned int)code);
set((Object *)key_group_tags[i].ti_Data, MUIA_ShortHelp, data->shorthelp[i]);
DoMethod
(
(Object *)key_group_tags[i].ti_Data, MUIM_Notify, MUIA_Pressed, FALSE,
(IPTR) self, 2, MUIM_ASCIITable_Insert, code
);
}
data->clip_req = CBOpen(0);
if (!data->clip_req)
{
showSimpleMessage(_(MSG_CANT_OPEN_CLIPDEVICE));
}
}
return (IPTR) self;
}
/*** OM_DISPOSE *************************************************************/
IPTR ASCIITable__OM_DISPOSE(Class *CLASS, Object *self, Msg message)
{
struct ASCIITable_DATA *data = INST_DATA(CLASS, self);
CBClose(data->clip_req);
return DoSuperMethodA(CLASS, self, message);
}
/*** MUIM_ASCIITable_Copy ***************************************************/
IPTR ASCIITable__MUIM_ASCIITable_Copy(Class *CLASS, Object *self, Msg msg)
{
struct ASCIITable_DATA *data = INST_DATA(CLASS, self);
CBWriteFTXT(data->clip_req, (CONST_STRPTR)XGET(data->ascii_string, MUIA_String_Contents));
return TRUE;
}
/*** MUIM_ASCIITable_Clear **************************************************/
IPTR ASCIITable__MUIM_ASCIITable_Clear(Class *CLASS, Object *self, Msg msg)
{
struct ASCIITable_DATA *data = INST_DATA(CLASS, self);
data->buffer[0] = '\0';
set(data->ascii_string, MUIA_String_Contents, "");
return TRUE;
}
/*** MUIM_ASCIITable_Insert *************************************************/
IPTR ASCIITable__MUIM_ASCIITable_Insert(Class *CLASS, Object *self, struct MUIP_ASCIITable_Insert *msg)
{
struct ASCIITable_DATA *data = INST_DATA(CLASS, self);
LONG len;
D(bug("insert code %d\n", msg->code));
strcpy(data->buffer, (CONST_STRPTR)XGET(data->ascii_string, MUIA_String_Contents));
len = strlen(data->buffer);
if (len < MAXLEN)
{
data->buffer[len] = msg->code;
data->buffer[len+1] = '\0';
set(data->ascii_string, MUIA_String_Contents, data->buffer);
}
return TRUE;
}
/*** Setup ******************************************************************/
ZUNE_CUSTOMCLASS_5
(
ASCIITable, NULL, MUIC_Group, NULL,
OM_NEW, struct opSet *,
OM_DISPOSE, Msg,
MUIM_ASCIITable_Copy, Msg,
MUIM_ASCIITable_Clear, Msg,
MUIM_ASCIITable_Insert, struct MUIP_ASCIITable_Insert *
);
/*** Begin application ******************************************************/
static CONST_STRPTR _(ULONG id)
{
if (LocaleBase != NULL && catalog != NULL)
{
return GetCatalogStr(catalog, id, CatCompArray[id].cca_Str);
}
else
{
return CatCompArray[id].cca_Str;
}
}
#define __(id) ((IPTR) _(id)) /* Get a message, as an IPTR */
/*** Locale_Initialize ******************************************************/
static int Locale_Initialize(VOID)
{
if (LocaleBase != NULL)
{
catalog = OpenCatalog
(
NULL, CATALOG_NAME, OC_Version, CATALOG_VERSION, TAG_DONE
);
}
else
{
catalog = NULL;
}
return TRUE;
}
/*** Locale_Deinitialize ****************************************************/
static VOID Locale_Deinitialize(VOID)
{
if (LocaleBase != NULL && catalog != NULL) CloseCatalog(catalog);
}
/*** GetArguments ***********************************************************/
static void GetArguments(int argc, char **argv)
{
static struct RDArgs *myargs;
static IPTR args[NUM_ARGS];
static UBYTE **wbargs;
static STRPTR cxname;
static struct WBStartup *argmsg;
static struct WBArg *wb_arg;
if (argc)
{
if (!(myargs = ReadArgs(ARG_TEMPLATE, args, NULL)))
{
Fault(IoErr(), 0, s, 256);
Cleanup(s);
}
if (args[ARG_CXPRI]) cx_pri = *(LONG*)args[ARG_CXPRI];
if (args[ARG_CXPOPKEY])
{
cx_popkey = StrDup((char *)args[ARG_CXPOPKEY]);
}
else
{
cx_popkey = StrDup(DEF_POPKEY);
}
if (args[ARG_CXPOPUP]) cx_popup = TRUE;
FreeArgs(myargs);
cxname = argv[0];
}
else
{
argmsg = (struct WBStartup *)argv;
wb_arg = argmsg->sm_ArgList;
cxname = wb_arg->wa_Name;
wbargs = ArgArrayInit(argc, (UBYTE**)argv);
cx_pri = ArgInt(wbargs, "CX_PRIORITY", 0);
cx_popkey = StrDup(ArgString(wbargs, "CX_POPKEY", DEF_POPKEY));
if (strnicmp(ArgString(wbargs, "CX_POPUP", "NO"), "Y", 1) == 0)
{
cx_popup = TRUE;
}
ArgArrayDone();
}
D(bug("ASCIITable Arguments pri %d popkey %s popup %d\n", cx_pri, cx_popkey, cx_popup));
disko = GetDiskObject(cxname);
}
/****************************************************************************/
static struct NewMenu nm[] =
{
{NM_TITLE, (STRPTR)MSG_MEN_PROJECT },
{NM_ITEM, (STRPTR)MSG_MEN_PROJECT_HIDE },
{NM_ITEM, (STRPTR)MSG_MEN_PROJECT_ICONIFY },
{NM_ITEM, NM_BARLABEL },
{NM_ITEM, (STRPTR)MSG_MEN_PROJECT_QUIT },
{NM_END }
};
/*** InitMenus **************************************************************/
static void InitMenus(void)
{
struct NewMenu *actnm = nm;
for(actnm = nm; actnm->nm_Type != NM_END; actnm++)
{
if (actnm->nm_Label != NM_BARLABEL)
{
ULONG id = (IPTR)actnm->nm_Label;
CONST_STRPTR str = _(id);
if (actnm->nm_Type == NM_TITLE)
{
actnm->nm_Label = str;
} else {
actnm->nm_Label = str + 2;
if (str[0] != ' ') actnm->nm_CommKey = str;
}
actnm->nm_UserData = (APTR)(IPTR)id;
} /* if (actnm->nm_Label != NM_BARLABEL) */
} /* for(actnm = nm; nm->nm_Type != NM_END; nm++) */
}
/*** showSimpleMessage ******************************************************/
static void showSimpleMessage(CONST_STRPTR msgString)
{
struct EasyStruct easyStruct;
easyStruct.es_StructSize = sizeof(easyStruct);
easyStruct.es_Flags = 0;
easyStruct.es_Title = _(MSG_ASCIITABLE_CXNAME);
easyStruct.es_TextFormat = msgString;
easyStruct.es_GadgetFormat = _(MSG_OK);
if (IntuitionBase != NULL && !Cli() )
{
EasyRequestArgs(NULL, &easyStruct, NULL, NULL);
}
else
{
PutStr(msgString);
}
}
/*** broker_func ************************************************************/
AROS_UFH3(void, broker_func,
AROS_UFHA(struct Hook *, h, A0),
AROS_UFHA(Object * , object, A2),
AROS_UFHA(CxMsg * , msg, A1))
{
AROS_USERFUNC_INIT
D(bug("ASCIITable: Broker hook called\n"));
if (CxMsgType(msg) == CXM_COMMAND)
{
if (CxMsgID(msg) == CXCMD_APPEAR)
{
CallHookPkt(&show_hook, NULL, NULL);
}
else if (CxMsgID(msg) == CXCMD_DISAPPEAR)
{
set(wnd, MUIA_Window_Open, FALSE);
}
}
AROS_USERFUNC_EXIT
}
/*** show_func ************************************************************/
AROS_UFH3(
void, show_func,
AROS_UFHA(struct Hook *, hook, A0),
AROS_UFHA(APTR *, obj, A2),
AROS_UFHA(APTR, param, A1)
)
{
AROS_USERFUNC_INIT
if (XGET(app, MUIA_Application_Iconified) == TRUE)
set(app, MUIA_Application_Iconified, FALSE);
else
set(wnd, MUIA_Window_Open, TRUE);
AROS_USERFUNC_EXIT
}
/*** MakeGUI ****************************************************************/
static void MakeGUI(void)
{
Object *menu;
static TEXT wintitle[100];
CxObj *popfilter;
menu = MUI_MakeObject(MUIO_MenustripNM, &nm, 0);
broker_hook.h_Entry = (HOOKFUNC)broker_func;
show_hook.h_Entry = (HOOKFUNC)show_func;
snprintf(wintitle, sizeof(wintitle), _(MSG_ASCIITABLE_WINTITLE), cx_popkey);
app = (Object *)ApplicationObject,
MUIA_Application_Title, __(MSG_ASCIITABLE_CXNAME),
MUIA_Application_Version, (IPTR)version,
MUIA_Application_Copyright, (IPTR)"Copyright © 2012, The AROS Development TEAM",
MUIA_Application_Author, (IPTR)"The AROS Development Team",
MUIA_Application_Description, __(MSG_ASCIITABLE_CXDESCR),
MUIA_Application_BrokerPri, cx_pri,
MUIA_Application_BrokerHook, (IPTR)&broker_hook,
MUIA_Application_Base, (IPTR)"ASCIITABLE",
MUIA_Application_SingleTask, TRUE,
MUIA_Application_Menustrip, (IPTR)menu,
MUIA_Application_DiskObject, (IPTR)disko,
SubWindow, (IPTR)(wnd = (Object *)WindowObject,
MUIA_Window_Title, (IPTR)wintitle,
MUIA_Window_ID, MAKE_ID('A', 'I', 'T', 'B'),
WindowContents, (IPTR)ASCIITableObject,
End,
End),
End;
if (! app)
Cleanup(NULL); // Propably double start
// enable hotkey
maintask = FindTask(NULL);
get(app, MUIA_Application_Broker, &broker);
get(app, MUIA_Application_BrokerPort, &brokermp);
if ( ! broker || ! brokermp)
Cleanup(_(MSG_CANT_CREATE_BROKER));
popfilter = CxFilter(cx_popkey);
if (popfilter)
{
CxObj *popsig = CxSignal(maintask, SIGBREAKB_CTRL_F);
if (popsig)
{
CxObj *trans;
AttachCxObj(popfilter, popsig);
trans = CxTranslate(NULL);
if (trans) AttachCxObj(popfilter, trans);
}
AttachCxObj(broker, popfilter);
}
DoMethod(wnd, MUIM_Notify, MUIA_Window_CloseRequest, TRUE,
(IPTR)wnd, 3, MUIM_Set, MUIA_Window_Open, FALSE);
DoMethod(app, MUIM_Notify, MUIA_Application_DoubleStart, TRUE,
(IPTR)wnd, 2, MUIM_CallHook, &show_hook);
DoMethod(wnd, MUIM_Notify, MUIA_Window_MenuAction, MSG_MEN_PROJECT_QUIT,
(IPTR)app, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit);
DoMethod(wnd, MUIM_Notify, MUIA_Window_MenuAction, MSG_MEN_PROJECT_HIDE,
(IPTR)wnd, 3, MUIM_Set, MUIA_Window_Open, FALSE);
DoMethod(wnd, MUIM_Notify, MUIA_Window_MenuAction, MSG_MEN_PROJECT_ICONIFY,
(IPTR)app, 3, MUIM_Set, MUIA_Application_Iconified, TRUE);
}
/*** HandleAll **************************************************************/
static void HandleAll(void)
{
ULONG sigs = 0;
set(wnd, MUIA_Window_Open, cx_popup);
while((LONG) DoMethod(app, MUIM_Application_NewInput, (IPTR)&sigs)
!= MUIV_Application_ReturnID_Quit)
{
if (sigs)
{
sigs = Wait(sigs | SIGBREAKF_CTRL_C | SIGBREAKF_CTRL_F);
if (sigs & SIGBREAKF_CTRL_C)
{
break;
}
if (sigs & SIGBREAKF_CTRL_F)
{
CallHookPkt(&show_hook, NULL, NULL);
}
}
}
}
/*** Cleanup ****************************************************************/
static void Cleanup(CONST_STRPTR txt)
{
MUI_DisposeObject(app);
FreeVec(cx_popkey);
FreeDiskObject(disko);
if (txt)
{
showSimpleMessage(txt);
exit(RETURN_ERROR);
}
exit(RETURN_OK);
}
/*** main *******************************************************************/
int main(int argc, char **argv)
{
D(bug("ASCIITable started\n"));
GetArguments(argc, argv);
InitMenus();
MakeGUI();
HandleAll();
Cleanup(NULL);
return RETURN_OK;
}
/****************************************************************************/
ADD2INIT(Locale_Initialize, 90);
ADD2EXIT(Locale_Deinitialize, 90);
获得新屏幕保护程序的最简单方法可能是复制随 AROS 附带的屏幕保护程序,然后执行自己的图形渲染
/*
Copyright � 1995-2006, The AROS Development Team. All rights reserved.
$Id$
*/
#include <aros/symbolsets.h>
#include <workbench/startup.h>
#include <intuition/intuition.h>
#include <intuition/intuitionbase.h>
#include <graphics/gfx.h>
#include <graphics/gfxbase.h>
#include <libraries/commodities.h>
#include <libraries/locale.h>
#include <proto/exec.h>
#include <proto/dos.h>
#include <proto/intuition.h>
#include <proto/graphics.h>
#include <proto/commodities.h>
#include <proto/alib.h>
#include <proto/locale.h>
#include <proto/icon.h>
#ifdef __AROS__
# include <aros/debug.h>
#else
# undef kprintf
# define kprintf(...) (void)0
# ifndef __MORPHOS__
typedef ULONG IPTR;
# endif
#endif
#include <stdio.h>
#include <stdlib.h>
#define CATCOMP_ARRAY
#include "strings.h"
#define CATALOG_NAME "System/Tools/Commodities.catalog"
#define CATALOG_VERSION 3
/************************************************************************************/
UBYTE version[] = "$VER: Blanker 0.11 (15.04.2006)";
#define ARG_TEMPLATE "CX_PRIORITY=PRI/N/K,SECONDS=SEC/N/K,STARS=ST/N/K"
#define ARG_PRI 0
#define ARG_SEC 1
#define ARG_STARS 2
#define NUM_ARGS 3
#define MAX_STARS 1000
#define CMD_STARTBLANK 1
#define CMD_STOPBLANK 2
#ifdef __MORPHOS__
static void BlankerAction(void);
static struct EmulLibEntry BlankerActionEntry =
{
TRAP_LIB,
0,
(void (*)(void))BlankerAction
};
#endif
static struct NewBroker nb =
{
NB_VERSION,
NULL,
NULL,
NULL,
NBU_NOTIFY | NBU_UNIQUE,
0,
0,
NULL,
0
};
static struct MsgPort *cxport;
static struct Window *win;
static struct RastPort *rp;
static struct ColorMap *cm;
static struct Task *maintask;
static struct Catalog *catalog;
static struct RDArgs *myargs;
static CxObj *cxbroker, *cxcust;
static ULONG cxmask, actionmask;
static WORD scrwidth, scrheight, actioncmd, visible_sky;
static LONG blackpen, star1pen, star2pen, star3pen;
static WORD num_stars = 200, blankwait = 30;
static UBYTE actionsig;
static BOOL blanked, quitme, disabled, pens_allocated;
static IPTR args[NUM_ARGS];
static char s[256];
static WORD star_x[MAX_STARS], star_y[MAX_STARS],
star_speed[MAX_STARS], star_col[MAX_STARS];
/************************************************************************************/
static CONST_STRPTR _(ULONG id)
{
if (LocaleBase != NULL && catalog != NULL)
{
return GetCatalogStr(catalog, id, CatCompArray[id].cca_Str);
}
else
{
return CatCompArray[id].cca_Str;
}
}
/************************************************************************************/
static BOOL Locale_Initialize(VOID)
{
if (LocaleBase != NULL)
{
catalog = OpenCatalog
(
NULL, CATALOG_NAME, OC_Version, CATALOG_VERSION, TAG_DONE
);
}
else
{
catalog = NULL;
}
return TRUE;
}
/************************************************************************************/
static VOID Locale_Deinitialize(VOID)
{
if(LocaleBase != NULL && catalog != NULL) CloseCatalog(catalog);
}
/************************************************************************************/
static void showSimpleMessage(CONST_STRPTR msgString)
{
struct EasyStruct easyStruct;
easyStruct.es_StructSize = sizeof(easyStruct);
easyStruct.es_Flags = 0;
easyStruct.es_Title = _(MSG_BLANKER_CXNAME);
easyStruct.es_TextFormat = msgString;
easyStruct.es_GadgetFormat = _(MSG_OK);
if (IntuitionBase != NULL && !Cli() )
{
EasyRequestArgs(NULL, &easyStruct, NULL, NULL);
}
else
{
PutStr(msgString);
}
}
/************************************************************************************/
static void FreePens(void)
{
if (pens_allocated)
{
ReleasePen(cm, blackpen);
ReleasePen(cm, star1pen);
ReleasePen(cm, star2pen);
ReleasePen(cm, star3pen);
pens_allocated = FALSE;
}
}
/************************************************************************************/
static void Cleanup(CONST_STRPTR msg)
{
struct Message *cxmsg;
if(msg)
{
puts(msg);
}
if(IntuitionBase)
{
if(win)
{
FreePens();
CloseWindow(win);
}
}
if(CxBase)
{
if(cxbroker)
DeleteCxObjAll(cxbroker);
if(cxport)
{
while((cxmsg = GetMsg(cxport)))
{
ReplyMsg(cxmsg);
}
DeleteMsgPort(cxport);
}
}
if(myargs)
FreeArgs(myargs);
if(actionsig)
FreeSignal(actionsig);
exit(0);
}
/************************************************************************************/
static void DosError(void)
{
Fault(IoErr(), 0, s, sizeof (s));
Cleanup(s);
}
/************************************************************************************/
static void Init(void)
{
maintask = FindTask(0);
actionsig = AllocSignal(-1);
actionmask = 1L << actionsig;
}
/************************************************************************************/
static void GetArguments(int argc, char **argv)
{
if (argc == 0)
{
UBYTE **array = ArgArrayInit(argc, (UBYTE **)argv);
nb.nb_Pri = ArgInt(array, "CX_PRIORITY", 0);
blankwait = ArgInt(array, "SECONDS" , blankwait);
num_stars = ArgInt(array, "STARS" , num_stars);
ArgArrayDone();
}
else
{
if (!(myargs = ReadArgs(ARG_TEMPLATE, args, 0)))
{
DosError();
}
if (args[ARG_PRI]) nb.nb_Pri = *(LONG *)args[ARG_PRI];
if (args[ARG_SEC]) blankwait = *(LONG *)args[ARG_SEC];
if (args[ARG_STARS]) num_stars = *(LONG *)args[ARG_STARS];
}
if (num_stars < 0)
{
num_stars = 0;
}
else if (num_stars > MAX_STARS)
{
num_stars = MAX_STARS;
}
}
/************************************************************************************/
#ifdef __MORPHOS__
static void BlankerAction(void)
#else
static void BlankerAction(CxMsg *msg,CxObj *obj)
#endif
{
#ifdef __MORPHOS__
CxMsg *msg = (CxMsg *)REG_A0;
CxObj *obj = (CxObj *)REG_A1;
#endif
struct InputEvent *ie = (struct InputEvent *)CxMsgData(msg);
static ULONG timecounter = 0;
if (ie->ie_Class == IECLASS_TIMER)
{
if (disabled)
{
timecounter = 0;
}
else if (!blanked)
{
timecounter++;
if(timecounter >= blankwait * 10)
{
actioncmd = CMD_STARTBLANK;
Signal(maintask, actionmask);
blanked = TRUE;
}
}
}
else if ((ie->ie_Class == IECLASS_RAWMOUSE) || (ie->ie_Class == IECLASS_RAWKEY))
{
if (ie->ie_Class != IECLASS_TIMER)
{
timecounter = 0;
if (blanked)
{
actioncmd = CMD_STOPBLANK;
Signal(maintask, actionmask);
blanked = FALSE;
}
}
}
}
/************************************************************************************/
static void InitCX(void)
{
if (!(cxport = CreateMsgPort()))
{
Cleanup(_(MSG_CANT_CREATE_MSGPORT));
}
nb.nb_Port = cxport;
cxmask = 1L << cxport->mp_SigBit;
if (!(cxbroker = CxBroker(&nb, 0)))
{
Cleanup(_(MSG_CANT_CREATE_BROKER));
}
#ifdef __MORPHOS__
if (!(cxcust = CxCustom(&BlankerActionEntry, 0)))
#else
if (!(cxcust = CxCustom(BlankerAction, 0)))
#endif
{
Cleanup(_(MSG_CANT_CREATE_CUSTOM));
}
AttachCxObj(cxbroker, cxcust);
ActivateCxObj(cxbroker, 1);
}
/************************************************************************************/
#define MY_RAND_MAX 32767
static LONG myrand(void)
{
static LONG a = 1;
return (a = a * 1103515245 + 12345) & MY_RAND_MAX;
}
/************************************************************************************/
static void HandleWin(void);
/************************************************************************************/
static void MakeWin(void)
{
struct Screen *screenPtr;
WORD y, y2, stripheight = 20;
LONG i;
if(!(screenPtr = LockPubScreen(NULL)))
kprintf("Warning: LockPubScreen() failed!\n");
win = OpenWindowTags(0, WA_Left, 0,
WA_Top, 0,
WA_Width, screenPtr->Width,
WA_Height, screenPtr->Height,
WA_AutoAdjust, TRUE,
WA_BackFill, (IPTR)LAYERS_NOBACKFILL,
WA_SimpleRefresh, TRUE,
WA_Borderless, TRUE,
TAG_DONE);
if(screenPtr)
UnlockPubScreen(NULL, screenPtr);
if(win)
{
rp = win->RPort;
scrwidth = win->Width;
scrheight = win->Height;
cm = win->WScreen->ViewPort.ColorMap;
blackpen = ObtainBestPenA(cm, 0x00000000, 0x00000000, 0x00000000, NULL);
star1pen = ObtainBestPenA(cm, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, NULL);
star2pen = ObtainBestPenA(cm, 0xAAAAAAAA, 0xAAAAAAAA, 0xAAAAAAAA, NULL);
star3pen = ObtainBestPenA(cm, 0x88888888, 0x88888888, 0x88888888, NULL);
pens_allocated = TRUE;
for(i = 0;i < num_stars;i++)
{
star_x[i] = myrand() * scrwidth / MY_RAND_MAX;
star_y[i] = 1 + (myrand() * (scrheight - 2)) / MY_RAND_MAX;
star_speed[i] = 1 + myrand() * 3 / MY_RAND_MAX;
if (star_speed[i] < 2)
{
star_col[i] = star3pen;
}
else if (star_speed[i] < 3)
{
star_col[i] = star2pen;
}
else
{
star_col[i] = star1pen;
}
}
SetAPen(rp, blackpen);
for(y = 0;y < scrheight - 1;y++, stripheight++)
{
if (CheckSignal(actionmask))
{
if (actioncmd == CMD_STOPBLANK)
{
FreePens();
CloseWindow(win);
win = 0;
break;
}
}
for(y2 = y;y2 < scrheight - 1;y2 += stripheight)
{
ClipBlit(rp, 0, y2, rp, 0, y2 + 1, scrwidth, scrheight - y2 - 1, 192);
SetAPen(rp, blackpen);
RectFill(rp, 0, y2, scrwidth - 1, y2);
#if 0
if (y2 == y)
{
for(i = 0; i < num_stars; i++)
{
if (star_y[i] == y2)
{
SetAPen(rp, star_col[i]);
WritePixel(rp, star_x[i], y2);
}
}
} /* if (y2 == y) */
#endif
} /* for(y2 = y;y2 < scrheight - 1;y2 += stripheight) */
visible_sky = y;
HandleWin();
WaitTOF();
} /* for(y = 0;y < scrheight - 1;y++, stripheight++) */
} /* if (win) */
else
{
showSimpleMessage(_(MSG_CANT_CREATE_WIN));
}
}
/************************************************************************************/
static void HandleWin(void)
{
LONG i;
for(i = 0; i < num_stars;i++)
{
if (star_y[i] <= visible_sky)
{
SetAPen(rp, blackpen);
WritePixel(rp, star_x[i], star_y[i]);
star_x[i] -= star_speed[i];
if (star_x[i] < 0) star_x[i] += scrwidth;
SetAPen(rp, star_col[i]);
WritePixel(rp, star_x[i], star_y[i]);
}
}
}
/************************************************************************************/
static void HandleAction(void)
{
switch(actioncmd)
{
case CMD_STARTBLANK:
if (!win) MakeWin();
break;
case CMD_STOPBLANK:
if (win)
{
FreePens();
CloseWindow(win);
win = 0;
}
break;
}
}
/************************************************************************************/
static void HandleCx(void)
{
CxMsg *msg;
while((msg = (CxMsg *)GetMsg(cxport)))
{
switch(CxMsgType(msg))
{
case CXM_COMMAND:
switch(CxMsgID(msg))
{
case CXCMD_DISABLE:
ActivateCxObj(cxbroker,0L);
disabled = TRUE;
break;
case CXCMD_ENABLE:
ActivateCxObj(cxbroker,1L);
disabled = FALSE;
break;
case CXCMD_UNIQUE:
case CXCMD_KILL:
quitme = TRUE;
break;
} /* switch(CxMsgID(msg)) */
break;
} /* switch (CxMsgType(msg))*/
ReplyMsg((struct Message *)msg);
} /* while((msg = (CxMsg *)GetMsg(cxport))) */
}
/************************************************************************************/
static void HandleAll(void)
{
ULONG sigs;
while(!quitme)
{
if (win)
{
HandleWin();
WaitTOF();
sigs = CheckSignal(cxmask | actionmask | SIGBREAKF_CTRL_C);
}
else
{
sigs = Wait(cxmask | actionmask | SIGBREAKF_CTRL_C);
}
if (sigs & cxmask) HandleCx();
if (sigs & actionmask) HandleAction();
if (sigs & SIGBREAKF_CTRL_C) quitme = TRUE;
} /* while(!quitme) */
}
/************************************************************************************/
int main(int argc, char **argv)
{
Init();
nb.nb_Name = _(MSG_BLANKER_CXNAME);
nb.nb_Title = _(MSG_BLANKER_CXTITLE);
nb.nb_Descr = _(MSG_BLANKER_CXDESCR);
GetArguments(argc, argv);
InitCX();
HandleAll();
Cleanup(0);
return 0;
}
/************************************************************************************/
ADD2INIT(Locale_Initialize, 90);
ADD2EXIT(Locale_Deinitialize, 90);
/*
Copyright © 1995-2012, The AROS Development Team. All rights reserved.
$Id$
*/
/*********************************************************************************************/
#include <intuition/classusr.h>
#include <graphics/layers.h>
#include <graphics/clip.h>
#include <libraries/asl.h>
#include <libraries/locale.h>
#include <libraries/gadtools.h>
#include <libraries/commodities.h>
#include <libraries/mui.h>
#include <workbench/startup.h>
#include <workbench/workbench.h>
#include <devices/inputevent.h>
#include <aros/asmcall.h>
#include <proto/exec.h>
#include <proto/dos.h>
#include <proto/locale.h>
#include <proto/muimaster.h>
#include <proto/intuition.h>
#include <proto/layers.h>
#include <proto/commodities.h>
#include <proto/alib.h>
#include <proto/icon.h>
#include <proto/utility.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define CATCOMP_ARRAY
#include "strings.h"
#define CATALOG_NAME "System/Tools/Commodities.catalog"
#define CATALOG_VERSION 3
#include <aros/debug.h>
/*********************************************************************************************/
#define VERSION 1
#define REVISION 6
#define DATESTR "14.01.2012"
#define VERSIONSTR "$VER: FKey 1.6 (" DATESTR ")"
/*********************************************************************************************/
#define ARG_TEMPLATE "CX_PRIORITY/N/K,CX_POPKEY/K,CX_POPUP/S,PORT/K,QUIET/S"
#define ARG_CXPRI 0
#define ARG_CXPOPKEY 1
#define ARG_CXPOPUP 2
#define ARG_CXPORT 3
#define ARG_QUIET 4
#define NUM_ARGS 5
/*********************************************************************************************/
#define ACTION_CYCLE_WIN 0
#define ACTION_CYCLE_SCR 1
#define ACTION_ENLARGE_WIN 2
#define ACTION_SHRINK_WIN 3
#define ACTION_TOGGLE_WIN 4
#define ACTION_RESCUE_WIN 5
#define ACTION_INSERT_TEXT 6
#define ACTION_RUN_PROG 7
#define ACTION_RUN_AREXX 8
#define RETURNID_NEWKEY 1
#define RETURNID_DELKEY 2
#define RETURNID_STRINGACK 3
#define RETURNID_LVACK 4
#define RETURNID_CMDACK 5
#define RETURNID_SAVE 6
#define RETURNID_DOUBLESTART 7
/*********************************************************************************************/
struct KeyInfo
{
struct InputEvent *translist;
CxObj *filter, *trans, *custom;
WORD action;
char descr[80];
char param[256];
};
/*********************************************************************************************/
struct LocaleBase *LocaleBase;
static char *cx_popkey = "ctrl alt f";
static LONG cx_pri = 0;
static BOOL cx_popup = FALSE;
static CxObj *broker, *activated_custom_cobj;
static Object *app, *wnd, *cmdcycle, *list, *liststr;
static Object *insertstr, *runprogstr, *runarexxstr;
static Object *cmdpage;
static struct Task *maintask;
static struct Hook keylist_construct_hook, keylist_destruct_hook, keylist_disp_hook;
static struct Hook broker_hook;
static struct Hook show_hook;
static struct MsgPort *brokermp;
static struct Catalog *catalog;
static struct RDArgs *myargs;
static struct WBStartup *wbstartup;
static LONG prog_exitcode;
static UBYTE **wbargs;
static IPTR args[NUM_ARGS];
static UBYTE s[257];
/*********************************************************************************************/
static void broker_func(struct Hook *hook, Object *obj, CxMsg *msg);
static UBYTE *BuildToolType(struct KeyInfo *ki);
static UBYTE **BuildToolTypes(UBYTE **src_ttypes);
static void Cleanup(CONST_STRPTR msg);
static void CleanupLocale(void);
static void CmdToKey(void);
static void DelKey(void);
static struct DiskObject *LoadProgIcon(BPTR *icondir, STRPTR iconname);
static void FreeArguments(void);
static void FreeToolTypes(UBYTE **ttypes);
static void GetArguments(int argc, char **argv);
static void HandleAction(void);
static void HandleAll(void);
static void InitCX(void);
static void InitLocale(STRPTR catname, ULONG version);
static void InitMenus(void);
static APTR keylist_construct_func(struct Hook *hook, APTR pool, struct KeyInfo *ki);
static void keylist_destruct_func(struct Hook *hook, APTR pool, struct KeyInfo *ki);
static void keylist_disp_func(struct Hook *hook, char **array, struct KeyInfo *ki);
static void KillCX(void);
static void KillGUI(void);
static void ListToString(void);
static void LoadSettings(void);
static void MakeGUI(void);
static CONST_STRPTR MSG(ULONG id);
static void NewKey(void);
static void RethinkAction(void);
static void RethinkKey(struct KeyInfo *ki);
static void SaveSettings(void);
static WORD ShowMessage(CONST_STRPTR title, CONST_STRPTR text, CONST_STRPTR gadtext);
static void StringToKey(void);
static struct DiskObject *disko;
/*********************************************************************************************/
static WORD ShowMessage(CONST_STRPTR title, CONST_STRPTR text, CONST_STRPTR gadtext)
{
struct EasyStruct es;
es.es_StructSize = sizeof(es);
es.es_Flags = 0;
es.es_Title = title;
es.es_TextFormat = text;
es.es_GadgetFormat = gadtext;
return EasyRequestArgs(NULL, &es, NULL, NULL);
}
/*********************************************************************************************/
static void Cleanup(CONST_STRPTR msg)
{
if (msg)
{
if (IntuitionBase && !((struct Process *)FindTask(NULL))->pr_CLI)
{
ShowMessage("Fkey", msg, MSG(MSG_OK));
}
else
{
printf("FKey: %s\n", msg);
}
}
KillGUI();
FreeDiskObject(disko);
FreeArguments();
KillCX();
CleanupLocale();
exit(prog_exitcode);
}
/*********************************************************************************************/
static void InitCX(void)
{
maintask = FindTask(NULL);
}
/*********************************************************************************************/
static void KillCX(void)
{
}
/*********************************************************************************************/
static void InitLocale(STRPTR catname, ULONG version)
{
LocaleBase = (struct LocaleBase *)OpenLibrary("locale.library", 39);
if (LocaleBase)
{
catalog = OpenCatalog(NULL, catname, OC_Version, version,
TAG_DONE);
}
}
/*********************************************************************************************/
static void CleanupLocale(void)
{
if (catalog) CloseCatalog(catalog);
if (LocaleBase) CloseLibrary((struct Library *)LocaleBase);
}
/*********************************************************************************************/
static CONST_STRPTR MSG(ULONG id)
{
if (catalog != NULL)
{
return GetCatalogStr(catalog, id, CatCompArray[id].cca_Str);
}
else
{
return CatCompArray[id].cca_Str;
}
}
/*********************************************************************************************/
static struct NewMenu nm[] =
{
{NM_TITLE, (STRPTR)MSG_MEN_PROJECT },
{NM_ITEM, (STRPTR)MSG_FKEY_MEN_PROJECT_SAVE },
{NM_ITEM, NM_BARLABEL },
{NM_ITEM, (STRPTR)MSG_MEN_PROJECT_HIDE },
{NM_ITEM, (STRPTR)MSG_MEN_PROJECT_ICONIFY },
{NM_ITEM, NM_BARLABEL },
{NM_ITEM, (STRPTR)MSG_MEN_PROJECT_QUIT },
{NM_END }
};
/*********************************************************************************************/
static void InitMenus(void)
{
struct NewMenu *actnm = nm;
for(actnm = nm; actnm->nm_Type != NM_END; actnm++)
{
if (actnm->nm_Label != NM_BARLABEL)
{
ULONG id = (IPTR)actnm->nm_Label;
CONST_STRPTR str = MSG(id);
if (actnm->nm_Type == NM_TITLE)
{
actnm->nm_Label = str;
} else {
actnm->nm_Label = str + 2;
if (str[0] != ' ') actnm->nm_CommKey = str;
}
actnm->nm_UserData = (APTR)(IPTR)id;
} /* if (actnm->nm_Label != NM_BARLABEL) */
} /* for(actnm = nm; nm->nm_Type != NM_END; nm++) */
}
/*********************************************************************************************/
static void FreeArguments(void)
{
if (myargs) FreeArgs(myargs);
ArgArrayDone();
}
/*********************************************************************************************/
static void KillGUI(void)
{
DisposeObject(app);
}
/*********************************************************************************************/
static void GetArguments(int argc, char **argv)
{
static struct WBArg *wb_arg;
static STRPTR cxname;
if (argc)
{
if (!(myargs = ReadArgs(ARG_TEMPLATE, args, NULL)))
{
Fault(IoErr(), 0, s, 256);
Cleanup(s);
}
if (args[ARG_CXPRI]) cx_pri = (LONG)*(IPTR *)args[ARG_CXPRI];
if (args[ARG_CXPOPKEY]) cx_popkey = (STRPTR)args[ARG_CXPOPKEY];
if (args[ARG_CXPOPUP]) cx_popup = TRUE;
cxname=argv[0];
}
else
{
wbstartup = (struct WBStartup *)argv;
wb_arg = wbstartup->sm_ArgList;
cxname = wb_arg->wa_Name;
wbargs = ArgArrayInit(argc, (UBYTE **)argv);
cx_pri = ArgInt(wbargs, "CX_PRIORITY", 0);
cx_popkey = ArgString(wbargs, "CX_POPKEY", cx_popkey);
if (strnicmp(ArgString(wbargs, "CX_POPUP", "NO"), "Y", 1) == 0)
{
cx_popup = TRUE;
}
}
disko = GetDiskObject(cxname);
}
/*********************************************************************************************/
static APTR keylist_construct_func(struct Hook *hook, APTR pool, struct KeyInfo *ki)
{
struct KeyInfo *new;
new = AllocPooled(pool, sizeof(*ki));
if (new) *new = *ki;
return new;
}
/*********************************************************************************************/
static void keylist_destruct_func(struct Hook *hook, APTR pool, struct KeyInfo *ki)
{
if (ki)
{
if (ki->filter) DeleteCxObjAll(ki->filter);
if (ki->translist) FreeIEvents(ki->translist);
FreePooled(pool, ki, sizeof(*ki));
}
}
/*********************************************************************************************/
static void keylist_disp_func(struct Hook *hook, char **array, struct KeyInfo *ki)
{
*array = ki->descr;
}
/*********************************************************************************************/
static void broker_func(struct Hook *hook, Object *obj, CxMsg *msg)
{
D(bug("FKey: broker_func called\n"));
if (CxMsgType(msg) == CXM_COMMAND)
{
if (CxMsgID(msg) == CXCMD_APPEAR)
{
CallHookPkt(&show_hook, NULL, NULL);
}
else if (CxMsgID(msg) == CXCMD_DISAPPEAR)
{
set(wnd, MUIA_Window_Open, FALSE);
}
}
}
/*** show_func ************************************************************/
AROS_UFH3(
void, show_func,
AROS_UFHA(struct Hook *, hook, A0),
AROS_UFHA(APTR *, obj, A2),
AROS_UFHA(APTR, param, A1)
)
{
AROS_USERFUNC_INIT
if (XGET(app, MUIA_Application_Iconified) == TRUE)
set(app, MUIA_Application_Iconified, FALSE);
else
set(wnd, MUIA_Window_Open, TRUE);
AROS_USERFUNC_EXIT
}
/*********************************************************************************************/
AROS_UFH2S(void, custom_func,
AROS_UFHA(CxMsg *, msg, A0),
AROS_UFHA(CxObj *, co, A1))
{
AROS_USERFUNC_INIT
activated_custom_cobj = co;
Signal(maintask, SIGBREAKF_CTRL_E);
AROS_USERFUNC_EXIT
}
/*********************************************************************************************/
static void MakeGUI(void)
{
static CONST_STRPTR cmdarray[] =
{
(CONST_STRPTR)MSG_FKEY_CMD_CYCLE_WIN,
(CONST_STRPTR)MSG_FKEY_CMD_CYCLE_SCR,
(CONST_STRPTR)MSG_FKEY_CMD_ENLARGE_WIN,
(CONST_STRPTR)MSG_FKEY_CMD_SHRINK_WIN,
(CONST_STRPTR)MSG_FKEY_CMD_TOGGLE_WIN_SIZE,
(CONST_STRPTR)MSG_FKEY_CMD_RESCUE_WIN,
(CONST_STRPTR)MSG_FKEY_CMD_INSERT_TEXT,
(CONST_STRPTR)MSG_FKEY_CMD_RUN_PROG,
(CONST_STRPTR)MSG_FKEY_CMD_RUN_AREXX,
0,
};
static TEXT wintitle[100];
WORD i;
Object *menu, *newkey, *delkey, *savekey;
for(i = 0; cmdarray[i]; i++)
{
cmdarray[i] = MSG((IPTR) cmdarray[i]);
}
keylist_construct_hook.h_Entry = HookEntry;
keylist_construct_hook.h_SubEntry = (HOOKFUNC)keylist_construct_func;
keylist_destruct_hook.h_Entry = HookEntry;
keylist_destruct_hook.h_SubEntry = (HOOKFUNC)keylist_destruct_func;
keylist_disp_hook.h_Entry = HookEntry;
keylist_disp_hook.h_SubEntry = (HOOKFUNC)keylist_disp_func;
broker_hook.h_Entry = HookEntry;
broker_hook.h_SubEntry = (HOOKFUNC)broker_func;
show_hook.h_Entry = (HOOKFUNC)show_func;
menu = MUI_MakeObject(MUIO_MenustripNM, &nm, 0);
snprintf(wintitle, sizeof(wintitle), MSG(MSG_FKEY_WINTITLE), cx_popkey);
app = ApplicationObject,
MUIA_Application_Title, (IPTR)MSG(MSG_FKEY_CXNAME),
MUIA_Application_Version, (IPTR)VERSIONSTR,
MUIA_Application_Copyright, (IPTR)"Copyright © 1995-2012, The AROS Development Team",
MUIA_Application_Author, (IPTR)"The AROS Development Team",
MUIA_Application_Description, (IPTR)MSG(MSG_FKEY_CXDESCR),
MUIA_Application_BrokerPri, cx_pri,
MUIA_Application_BrokerHook, (IPTR)&broker_hook,
MUIA_Application_Base, (IPTR)"FKey",
MUIA_Application_SingleTask, TRUE,
menu ? MUIA_Application_Menustrip : TAG_IGNORE, menu,
MUIA_Application_DiskObject, (IPTR)disko,
SubWindow, wnd = WindowObject,
MUIA_Window_Title, (IPTR)wintitle,
MUIA_Window_ID, MAKE_ID('F','W','I','N'),
WindowContents, HGroup,
Child, VGroup,
GroupFrameT(MSG(MSG_FKEY_DEFINED_KEYS)),
Child, VGroup,
GroupSpacing(0),
Child, ListviewObject,
MUIA_Listview_List, list = ListObject,
InputListFrame,
MUIA_List_ConstructHook, (IPTR)&keylist_construct_hook,
MUIA_List_DestructHook, (IPTR)&keylist_destruct_hook,
MUIA_List_DisplayHook, (IPTR)&keylist_disp_hook,
End,
End,
Child, liststr = StringObject,
MUIA_Disabled, TRUE,
StringFrame,
End,
End,
Child, HGroup,
Child, newkey = SimpleButton(MSG(MSG_FKEY_NEW_KEY)),
Child, delkey = SimpleButton(MSG(MSG_FKEY_DELETE_KEY)),
End,
Child, savekey = SimpleButton(MSG(MSG_FKEY_SAVE_KEY)),
End,
Child, VGroup,
GroupFrameT(MSG(MSG_FKEY_COMMAND)),
Child, cmdcycle = MUI_MakeObject(MUIO_Cycle, NULL, cmdarray),
Child, cmdpage = PageGroup,
Child, HVSpace, /* cycle win */
Child, HVSpace, /* cycle scr */
Child, HVSpace, /* enlarge win */
Child, HVSpace, /* shrink win */
Child, HVSpace, /* Toggle win */
Child, HVSpace, /* rescue win */
Child, insertstr = StringObject, StringFrame, End, /* Insert text */
Child, PopaslObject, /* Run prog */
MUIA_Popstring_String, runprogstr = StringObject, StringFrame, End,
MUIA_Popstring_Button, PopButton(MUII_PopFile),
ASLFR_RejectIcons, TRUE,
End,
Child, PopaslObject, /* Run AREXX */
MUIA_Popstring_String, runarexxstr = StringObject, StringFrame, End,
MUIA_Popstring_Button, PopButton(MUII_PopFile),
ASLFR_RejectIcons, TRUE,
End,
End,
Child, HVSpace,
End,
End,
End,
End;
if (!app)
{
#if 1
Cleanup(NULL); /* Make no noise. Is ugly if FKey is double-started. */
#else
Cleanup(MSG(MSG_CANT_CREATE_GADGET));
#endif
}
get(app, MUIA_Application_Broker, &broker);
get(app, MUIA_Application_BrokerPort, &brokermp);
if (!broker || !brokermp)
Cleanup(MSG(MSG_CANT_CREATE_GADGET));
{
CxObj *popfilter = CxFilter(cx_popkey);
if (popfilter)
{
CxObj *popsig = CxSignal(maintask, SIGBREAKB_CTRL_F);
if (popsig)
{
CxObj *trans;
AttachCxObj(popfilter, popsig);
trans = CxTranslate(NULL);
if (trans) AttachCxObj(popfilter, trans);
}
AttachCxObj(broker, popfilter);
}
}
set(liststr, MUIA_String_AttachedList, (IPTR)list);
DoMethod(app, MUIM_Notify, MUIA_Application_DoubleStart, TRUE, (IPTR) app, 2, MUIM_Application_ReturnID, RETURNID_DOUBLESTART);
DoMethod(wnd, MUIM_Notify, MUIA_Window_CloseRequest, TRUE, (IPTR) wnd, 3, MUIM_Set, MUIA_Window_Open, FALSE);
DoMethod(wnd, MUIM_Notify, MUIA_Window_MenuAction, MSG_MEN_PROJECT_QUIT, (IPTR) app, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit);
DoMethod(wnd, MUIM_Notify, MUIA_Window_MenuAction, MSG_MEN_PROJECT_HIDE, (IPTR) wnd, 3, MUIM_Set, MUIA_Window_Open, FALSE);
DoMethod(wnd, MUIM_Notify, MUIA_Window_MenuAction, MSG_MEN_PROJECT_ICONIFY, (IPTR) app, 3, MUIM_Set, MUIA_Application_Iconified, TRUE);
DoMethod(wnd, MUIM_Notify, MUIA_Window_MenuAction, MSG_FKEY_MEN_PROJECT_SAVE, (IPTR) app, 2, MUIM_Application_ReturnID, RETURNID_SAVE);
DoMethod(cmdcycle, MUIM_Notify, MUIA_Cycle_Active, MUIV_EveryTime, (IPTR)cmdpage, 3, MUIM_Set, MUIA_Group_ActivePage, MUIV_TriggerValue);
DoMethod(cmdcycle, MUIM_Notify, MUIA_Cycle_Active, MUIV_EveryTime, (IPTR)app, 2, MUIM_Application_ReturnID, RETURNID_CMDACK);
DoMethod(newkey, MUIM_Notify, MUIA_Pressed, FALSE, (IPTR)app, 2, MUIM_Application_ReturnID, RETURNID_NEWKEY);
DoMethod(delkey, MUIM_Notify, MUIA_Pressed, FALSE, (IPTR)app, 2, MUIM_Application_ReturnID, RETURNID_DELKEY);
DoMethod(savekey, MUIM_Notify, MUIA_Pressed, FALSE, (IPTR)app, 2, MUIM_Application_ReturnID, RETURNID_SAVE);
DoMethod(list, MUIM_Notify, MUIA_List_Active, MUIV_EveryTime, (IPTR)app, 2, MUIM_Application_ReturnID, RETURNID_LVACK);
DoMethod(liststr, MUIM_Notify, MUIA_String_Acknowledge, MUIV_EveryTime, (IPTR)app, 2, MUIM_Application_ReturnID, RETURNID_STRINGACK);
DoMethod(insertstr, MUIM_Notify, MUIA_String_Acknowledge, MUIV_EveryTime, (IPTR)app, 2, MUIM_Application_ReturnID, RETURNID_CMDACK);
DoMethod(runprogstr, MUIM_Notify, MUIA_String_Acknowledge, MUIV_EveryTime, (IPTR)app, 2, MUIM_Application_ReturnID, RETURNID_CMDACK);
DoMethod(runarexxstr, MUIM_Notify, MUIA_String_Acknowledge, MUIV_EveryTime, (IPTR)app, 2, MUIM_Application_ReturnID, RETURNID_CMDACK);
}
/*********************************************************************************************/
static void RethinkKey(struct KeyInfo *ki)
{
if (ki->filter) DeleteCxObjAll(ki->filter);
if (ki->translist)
{
FreeIEvents(ki->translist);
ki->translist = NULL;
}
ki->custom = ki->trans = ki->filter = NULL;
if ((ki->filter = CxFilter(ki->descr)))
{
switch(ki->action)
{
case ACTION_INSERT_TEXT:
strrev(ki->param);
if ((ki->translist = InvertStringForwd(ki->param, NULL)))
{
if ((ki->trans = CxTranslate(ki->translist)))
{
AttachCxObj(ki->filter, ki->trans);
}
}
strrev(ki->param);
break;
default:
/* This CxCustom thing is hacky/ugly. A CxSender
would be better, but if want to send a pointer
with it then this would require some fixes in
commodities.library and it's header in case we are
running on 64 bit machines :-\ */
if ((ki->custom = CxCustom(custom_func, 0)))
{
AttachCxObj(ki->filter, ki->custom);
if ((ki->trans = CxTranslate(NULL)))
{
AttachCxObj(ki->filter, ki->trans);
}
}
break;
}
AttachCxObj(broker, ki->filter);
}
}
/*********************************************************************************************/
static void RethinkAction(void)
{
struct KeyInfo *ki = NULL;
DoMethod(list, MUIM_List_GetEntry, MUIV_List_GetEntry_Active, (IPTR)&ki);
if (ki)
{
Object *str = NULL;
IPTR val = 0;
get(cmdcycle, MUIA_Cycle_Active, &val);
ki->action = val;
switch(ki->action)
{
case ACTION_INSERT_TEXT:
str = insertstr;
break;
case ACTION_RUN_PROG:
str = runprogstr;
break;
case ACTION_RUN_AREXX:
str = runarexxstr;
break;
}
if (str)
{
STRPTR s = "";
get(str, MUIA_String_Contents, &s);
strncpy(ki->param, s, sizeof(ki->param));
}
RethinkKey(ki);
}
}
/*********************************************************************************************/
static void NewKey(void)
{
struct KeyInfo ki = {0};
StringToKey();
DoMethod(list, MUIM_List_InsertSingle, (IPTR)&ki, MUIV_List_Insert_Bottom);
nnset(list, MUIA_List_Active, MUIV_List_Active_Bottom);
nnset(liststr, MUIA_String_Contents, "");
nnset(liststr, MUIA_Disabled, FALSE);
set(wnd, MUIA_Window_ActiveObject, (IPTR)liststr);
RethinkAction();
}
/*********************************************************************************************/
static void DelKey(void)
{
struct KeyInfo *ki = NULL;
DoMethod(list, MUIM_List_GetEntry, MUIV_List_GetEntry_Active, (IPTR)&ki);
if (ki)
{
DoMethod(list, MUIM_List_Remove, MUIV_List_Remove_Active);
DoMethod(list, MUIM_List_GetEntry, MUIV_List_GetEntry_Active, (IPTR)&ki);
if (!ki)
{
nnset(liststr, MUIA_String_Contents, (IPTR)"");
nnset(liststr, MUIA_Disabled, TRUE);
ListToString();
}
}
}
/*********************************************************************************************/
static void StringToKey(void)
{
struct KeyInfo *ki = NULL;
STRPTR text = "";
DoMethod(list, MUIM_List_GetEntry, MUIV_List_GetEntry_Active, (IPTR)&ki);
if (!ki) return;
get(liststr, MUIA_String_Contents, &text);
strncpy(ki->descr, text, sizeof(ki->descr));
DoMethod(list, MUIM_List_Redraw, MUIV_List_Redraw_Active);
RethinkKey(ki);
}
/*********************************************************************************************/
static void ListToString(void)
{
struct KeyInfo *ki = NULL;
DoMethod(list, MUIM_List_GetEntry, MUIV_List_GetEntry_Active, (IPTR)&ki);
if (!ki) return;
nnset(liststr, MUIA_Disabled, FALSE);
nnset(liststr, MUIA_String_Contents, ki->descr);
switch(ki->action)
{
case ACTION_INSERT_TEXT:
nnset(insertstr, MUIA_String_Contents, ki->param);
break;
case ACTION_RUN_PROG:
nnset(runprogstr, MUIA_String_Contents, ki->param);
break;
case ACTION_RUN_AREXX:
nnset(runarexxstr, MUIA_String_Contents, ki->param);
break;
}
nnset(cmdcycle, MUIA_Cycle_Active, ki->action);
nnset(cmdpage, MUIA_Group_ActivePage, ki->action);
}
/*********************************************************************************************/
static void CmdToKey(void)
{
RethinkAction();
}
/*********************************************************************************************/
static void HandleAction(void)
{
struct KeyInfo *ki;
struct Window *win;
struct Screen *scr;
CxObj *cobj;
WORD i;
cobj = activated_custom_cobj;
activated_custom_cobj = NULL;
for(i = 0; ; i++)
{
DoMethod(list, MUIM_List_GetEntry, i, (IPTR)&ki);
if (!ki) break;
if (ki->custom == cobj) break;
}
if (!ki) return;
win = IntuitionBase->ActiveWindow;
scr = IntuitionBase->FirstScreen;
switch(ki->action)
{
case ACTION_CYCLE_WIN:
if (win)
{
struct Layer *lay;
scr = win->WScreen;
win = NULL;
LockLayerInfo(&scr->LayerInfo);
lay = scr->LayerInfo.top_layer;
while(lay)
{
if (lay->Window &&
(lay != scr->BarLayer) &&
!(lay->Flags & LAYERBACKDROP) &&
!(((struct Window *)lay->Window)->Flags & WFLG_BORDERLESS))
{
win = (struct Window *)lay->Window;
}
lay = lay->back;
}
UnlockLayerInfo(&scr->LayerInfo);
if (win)
{
WindowToFront(win);
ActivateWindow(win);
}
}
break;
case ACTION_CYCLE_SCR:
if (scr) ScreenToBack(scr);
break;
case ACTION_ENLARGE_WIN:
if (win && (win->Flags & WFLG_SIZEGADGET))
{
WORD neww = win->MaxWidth;
WORD newh = win->MaxHeight;
if (neww > win->WScreen->Width) neww = win->WScreen->Width;
if (newh > win->WScreen->Height) newh = win->WScreen->Height;
ChangeWindowBox(win, win->LeftEdge, win->TopEdge, neww, newh);
}
break;
case ACTION_SHRINK_WIN:
if (win && (win->Flags & WFLG_SIZEGADGET))
{
WORD neww = win->MinWidth;
WORD newh = win->MinHeight;
ChangeWindowBox(win, win->LeftEdge, win->TopEdge, neww, newh);
}
break;
case ACTION_RESCUE_WIN:
if (win)
{
WORD dx = 0, dy = 0;
if (win->LeftEdge < 0)
dx = -win->LeftEdge;
else if (win->LeftEdge + win->Width > win->WScreen->Width)
dx = win->WScreen->Width - win->Width - win->LeftEdge;
if (win->TopEdge + win->Height > win->WScreen->Height)
dy = win->WScreen->Height - win->Height - win->TopEdge;
else if (win->TopEdge < win->WScreen->BarHeight)
{
// try to keep the screen title bar visible
if (win->WScreen->BarHeight + win->Height < win->WScreen->Height)
dy = -win->TopEdge + win->WScreen->BarHeight;
else
dy = win->WScreen->Height - win->Height - win->TopEdge;
}
MoveWindow(win, dx, dy);
}
break;
case ACTION_TOGGLE_WIN:
if (win) ZipWindow(win);
break;
case ACTION_RUN_PROG:
if (ki->param)
{
BPTR infh;
infh = Open("CON:20/20/500/300/FKey/CLOSE/AUTO/WAIT", MODE_READWRITE);
if (infh)
{
struct TagItem systemtags[] =
{
{SYS_Asynch , TRUE },
{SYS_Input , (IPTR)infh},
{SYS_Output , 0 },
{TAG_DONE }
};
if (SystemTagList(ki->param, systemtags) == -1)
{
/* Error */
Close(infh);
}
}
}
break;
case ACTION_RUN_AREXX:
break;
} /* switch(ki->action) */
}
/*********************************************************************************************/
#define QUOTE_START 0xAB
#define QUOTE_END 0xBB
/*********************************************************************************************/
static UBYTE *BuildToolType(struct KeyInfo *ki)
{
static UBYTE ttstring[500];
UBYTE *param1 = "";
UBYTE *param2 = "";
switch(ki->action)
{
case ACTION_CYCLE_WIN:
param1 = "CYCLE";
break;
case ACTION_CYCLE_SCR:
param1 = "CYCLESCREEN";
break;
case ACTION_ENLARGE_WIN:
param1 = "MAKEBIG";
break;
case ACTION_SHRINK_WIN:
param1 = "MAKESMALL";
break;
case ACTION_TOGGLE_WIN:
param1 = "ZIPWINDOW";
break;
case ACTION_RESCUE_WIN:
param1 = "RESCUEWIN";
break;
case ACTION_INSERT_TEXT:
param1 = "INSERT ";
param2 = ki->param;
break;
case ACTION_RUN_PROG:
param1 = "RUN ";
param2 = ki->param;
break;
case ACTION_RUN_AREXX:
param1 = "AREXX ";
param2 = ki->param;
break;
}
snprintf(ttstring, sizeof(ttstring), "%c%s%c %s%s",
QUOTE_START,
ki->descr,
QUOTE_END,
param1,
param2);
return ttstring;
}
/*********************************************************************************************/
static UBYTE **BuildToolTypes(UBYTE **src_ttypes)
{
APTR pool = CreatePool(MEMF_CLEAR, 200, 200);
Object *listobj = list;
UBYTE *tt;
WORD list_index = 0, num_ttypes = 0, alloc_ttypes = 10;
UBYTE **dst_ttypes;
if (!pool) return NULL;
dst_ttypes = AllocPooled(pool, (alloc_ttypes + 2) * sizeof(UBYTE *));
if (!dst_ttypes)
{
DeletePool(pool);
return NULL;
}
/* Put together final tooltypes list based on old tooltypes and
new tooltypes all in one loop */
for(;;)
{
tt = NULL;
if (listobj)
{
/* New tooltypes */
struct KeyInfo *ki = NULL;
DoMethod(listobj, MUIM_List_GetEntry, list_index, (IPTR)&ki);
list_index++;
if (ki)
{
tt = BuildToolType(ki);
}
else
{
listobj = NULL;
}
}
if (!listobj)
{
/* Old tooltypes */
if (src_ttypes) tt = *src_ttypes++;
if (!tt) break; /* Done. Skip out of "for(;;)" loop */
if (tt[0] == QUOTE_START) continue; /* skip tooltype containing old settings */
}
if (!tt) break; /* Paranoia. Should not happen. */
if (num_ttypes >= alloc_ttypes)
{
UBYTE **new_dst_ttypes = AllocPooled(pool, (alloc_ttypes + 10 + 2) * sizeof(UBYTE *));
if (!new_dst_ttypes)
{
DeletePool(pool);
return NULL;
}
CopyMem(dst_ttypes + 1, new_dst_ttypes + 1, alloc_ttypes * sizeof(UBYTE *));
dst_ttypes = new_dst_ttypes;
alloc_ttypes += 10;
}
dst_ttypes[num_ttypes + 1] = AllocPooled(pool, strlen(tt) + 1);
if (!dst_ttypes[num_ttypes + 1])
{
DeletePool(pool);
return NULL;
}
CopyMem(tt, dst_ttypes[num_ttypes + 1], strlen(tt) + 1);
num_ttypes++;
}
dst_ttypes[0] = (APTR)pool;
return dst_ttypes + 1;
}
/*********************************************************************************************/
static void FreeToolTypes(UBYTE **ttypes)
{
if (ttypes)
{
DeletePool((APTR)ttypes[-1]);
}
}
/*********************************************************************************************/
static struct DiskObject *LoadProgIcon(BPTR *icondir, STRPTR iconname)
{
struct DiskObject *progicon = NULL;
if (wbstartup)
{
BPTR olddir;
*icondir = wbstartup->sm_ArgList[0].wa_Lock;
olddir = CurrentDir(*icondir);
progicon = GetDiskObject(wbstartup->sm_ArgList[0].wa_Name);
CurrentDir(olddir);
strncpy(iconname, wbstartup->sm_ArgList[0].wa_Name, 255);
}
else
{
if (GetProgramName(iconname, 255))
{
BPTR olddir;
*icondir = GetProgramDir();
olddir = CurrentDir(*icondir);
progicon = GetDiskObject(iconname);
CurrentDir(olddir);
}
}
return progicon;
}
/*********************************************************************************************/
static void SaveSettings(void)
{
struct DiskObject *progicon;
UBYTE **ttypes, **old_ttypes;
UBYTE iconname[256];
BPTR icondir = BNULL;
progicon = LoadProgIcon(&icondir, iconname);
if (!progicon) return;
old_ttypes = (UBYTE **)progicon->do_ToolTypes;
if ((ttypes = BuildToolTypes(old_ttypes)))
{
BPTR olddir;
#if 0 /* DEBUG */
UBYTE *tt, **ttypes_copy = ttypes;
while((tt = *ttypes_copy++))
{
kprintf("TT: %s\n", tt);
}
#endif
olddir = CurrentDir(icondir);
progicon->do_ToolTypes = ttypes;
PutDiskObject(iconname, progicon);
progicon->do_ToolTypes = old_ttypes;
CurrentDir(olddir);
FreeToolTypes(ttypes);
}
FreeDiskObject(progicon);
}
/*********************************************************************************************/
static void LoadSettings(void)
{
struct DiskObject *progicon;
UBYTE iconname[256];
BPTR icondir = BNULL;
UBYTE **ttypes, *tt;
progicon = LoadProgIcon(&icondir, iconname);
if (!progicon) return;
if ((ttypes = (UBYTE **)progicon->do_ToolTypes))
{
while((tt = *ttypes++))
{
struct KeyInfo ki = {0};
UBYTE *quote_end;
ki.action = 0xFF;
if ((tt[0] == QUOTE_START) && ((quote_end = strchr(tt, (char)QUOTE_END))))
{
WORD len = quote_end - tt - 1;
if (len >= sizeof(ki.descr)) continue;
if (quote_end[1] != ' ') continue;
strncpy(ki.descr, tt + 1, len);
if (strncmp(quote_end + 2, "CYCLE", 5 + 1) == 0)
{
ki.action = ACTION_CYCLE_WIN;
}
else if (strncmp(quote_end + 2, "CYCLESCREEN", 11 + 1) == 0)
{
ki.action = ACTION_CYCLE_SCR;
}
else if (strncmp(quote_end + 2, "MAKEBIG", 7 + 1) == 0)
{
ki.action = ACTION_ENLARGE_WIN;
}
else if (strncmp(quote_end + 2, "MAKESMALL", 9 + 1) == 0)
{
ki.action = ACTION_SHRINK_WIN;
}
else if (strncmp(quote_end + 2, "ZIPWINDOW", 9 + 1) == 0)
{
ki.action = ACTION_TOGGLE_WIN;
}
else if (strncmp(quote_end + 2, "RESCUEWIN", 9 + 1) == 0)
{
ki.action = ACTION_RESCUE_WIN;
}
else if (strncmp(quote_end + 2, "INSERT ", 7) == 0)
{
ki.action = ACTION_INSERT_TEXT;
strncpy(ki.param, quote_end + 2 + 7, sizeof(ki.param) - 1);
}
else if (strncmp(quote_end + 2, "RUN ", 4) == 0)
{
ki.action = ACTION_RUN_PROG;
strncpy(ki.param, quote_end + 2 + 4, sizeof(ki.param) - 1);
}
else if (strncmp(quote_end + 2, "AREXX ", 6) == 0)
{
ki.action = ACTION_RUN_AREXX;
strncpy(ki.param, quote_end + 2 + 6, sizeof(ki.param) - 1);
}
if (ki.action != 0xFF)
{
DoMethod(list, MUIM_List_InsertSingle, (IPTR)&ki, MUIV_List_Insert_Bottom);
}
} /* if ((tt[0] == QUOTE_START) && ((quote_end = strchr(tt, QUOTE_END)))) */
} /* while((tt = *ttypes++)) */
{
LONG index;
for(index = 0; ; index++)
{
struct KeyInfo *ki = NULL;
DoMethod(list, MUIM_List_GetEntry, index, (IPTR)&ki);
if (!ki) break;
RethinkKey(ki);
}
}
} /* if ((ttypes = (UBYTE **)progicon->do_ToolTypes)) */
FreeDiskObject(progicon);
}
/*********************************************************************************************/
static void HandleAll(void)
{
ULONG sigs = 0;
LONG returnid;
IPTR num_list_entries = 0;
get(list, MUIA_List_Entries, &num_list_entries);
if ((num_list_entries == 0) || cx_popup)
{
set(wnd, MUIA_Window_Open, TRUE);
}
else
{
set(wnd, MUIA_Window_Open, FALSE);
}
for(;;)
{
returnid = (LONG) DoMethod(app, MUIM_Application_NewInput, (IPTR) &sigs);
if (returnid == MUIV_Application_ReturnID_Quit) break;
switch(returnid)
{
case RETURNID_NEWKEY:
NewKey();
break;
case RETURNID_DELKEY:
DelKey();
break;
case RETURNID_LVACK:
ListToString();
break;
case RETURNID_STRINGACK:
StringToKey();
break;
case RETURNID_CMDACK:
CmdToKey();
break;
case RETURNID_SAVE:
SaveSettings();
break;
case RETURNID_DOUBLESTART:
CallHookPkt(&show_hook, NULL, NULL);
break;
}
if (sigs)
{
sigs = Wait(sigs | SIGBREAKF_CTRL_C | SIGBREAKF_CTRL_E | SIGBREAKF_CTRL_F);
if (sigs & SIGBREAKF_CTRL_C) break;
if (sigs & SIGBREAKF_CTRL_E) HandleAction();
if (sigs & SIGBREAKF_CTRL_F)
{
CallHookPkt(&show_hook, NULL, NULL);
}
}
}
}
/*********************************************************************************************/
int main(int argc, char **argv)
{
GetArguments(argc, argv);
InitLocale(CATALOG_NAME, CATALOG_VERSION);
InitCX();
InitMenus();
MakeGUI();
LoadSettings();
HandleAll();
Cleanup(NULL);
return 0;
}
/*
Copyright © 1995-2008, The AROS Development Team. All rights reserved.
$Id: ClickToFront.c 31657 2009-08-03 13:08:00Z mazze $
ClickToFront commodity -- puts windows to front when clicked in.
*/
/******************************************************************************
NAME
ClickToFront
SYNOPSIS
CX_PRIORITY/N/K, QUALIFIER/K, NUMCLICKS/N/K
LOCATION
SYS:Tools/Commodities
FUNCTION
Automatically raises and activates a window when clicking in it.
INPUTS
CX_PRIORITY -- The priority of the commodity
QUALIFIER -- Qualifier to match the clicks (LEFT_ALT, RIGHT_ALT,
CTRL or NONE).
NUMCLICKS -- Number of clicks to bring window to front. Value
must be greater than 0.
RESULT
NOTES
EXAMPLE
BUGS
SEE ALSO
INTERNALS
******************************************************************************/
#include <aros/symbolsets.h>
#include <workbench/startup.h>
#include <intuition/intuition.h>
#include <intuition/intuitionbase.h>
#include <libraries/commodities.h>
#include <libraries/locale.h>
#include <proto/exec.h>
#include <proto/dos.h>
#include <proto/intuition.h>
#include <proto/layers.h>
#include <proto/commodities.h>
#include <proto/input.h>
#include <proto/alib.h>
#include <proto/locale.h>
#include <proto/icon.h>
#include <stdio.h>
#define DEBUG 0
#include <aros/debug.h>
#define CATCOMP_ARRAY
#include "strings.h"
#define CATALOG_NAME "System/Tools/Commodities.catalog"
#define CATALOG_VERSION 3
/***************************************************************************/
UBYTE version[] = "$VER: ClickToFront 0.4 (13.10.2008)";
#define ARG_TEMPLATE "CX_PRIORITY=PRI/N/K,QUALIFIER/K,NUMCLICKS=CLICKS/N/K"
#define ARG_PRI 0
#define ARG_QUALIFIER 1
#define ARG_CLICKS 2
#define NUM_ARGS 3
struct Device *InputBase = NULL;
struct Catalog *catalog;
struct IOStdReq *inputIO;
/* The ClickToFront broker */
static struct NewBroker nb =
{
NB_VERSION,
NULL,
NULL,
NULL,
NBU_NOTIFY | NBU_UNIQUE,
0,
0,
NULL,
0
};
typedef struct _CFState
{
CxObj *cs_broker;
struct MsgPort *cs_msgPort;
} CFState;
typedef struct CF
{
struct Window *ci_thisWindow;
struct Window *ci_lastWindow;
UWORD ci_qualifiers; /* Qualifiers that must match */
BOOL ci_mouseHasMoved;
ULONG ci_clicksToDo; /* Bring to front after how many clicks? */
ULONG ci_clicksDone; /* How many clicks are we already aware of? */
ULONG ci_lcSeconds; /* Time stamp for the last click */
ULONG ci_lcMicros;
} CF;
static CF cfInfo =
{
NULL,
NULL,
0,
FALSE,
0,
0,
0,
0
};
/************************************************************************************/
static void freeResources(CFState *cs);
static BOOL initiate(int argc, char **argv, CFState *cs);
static void getQualifier(STRPTR qualString);
static void clicktoFront(CxMsg *msg, CxObj *co);
static CONST_STRPTR _(ULONG id);
static BOOL Locale_Initialize(VOID);
static VOID Locale_Deinitialize(VOID);
static void showSimpleMessage(CONST_STRPTR msgString);
/************************************************************************************/
static CONST_STRPTR _(ULONG id)
{
if (LocaleBase != NULL && catalog != NULL)
{
return GetCatalogStr(catalog, id, CatCompArray[id].cca_Str);
}
else
{
return CatCompArray[id].cca_Str;
}
}
/************************************************************************************/
static BOOL Locale_Initialize(VOID)
{
if (LocaleBase != NULL)
{
catalog = OpenCatalog(NULL, CATALOG_NAME, OC_Version, CATALOG_VERSION,
TAG_DONE);
}
else
{
catalog = NULL;
}
return TRUE;
}
/************************************************************************************/
static VOID Locale_Deinitialize(VOID)
{
if(LocaleBase != NULL && catalog != NULL) CloseCatalog(catalog);
}
/************************************************************************************/
static void showSimpleMessage(CONST_STRPTR msgString)
{
struct EasyStruct easyStruct;
easyStruct.es_StructSize = sizeof(easyStruct);
easyStruct.es_Flags = 0;
easyStruct.es_Title = _(MSG_CLICK2FNT_CXNAME);
easyStruct.es_TextFormat = msgString;
easyStruct.es_GadgetFormat = _(MSG_OK);
if (IntuitionBase != NULL && !Cli() )
{
EasyRequestArgs(NULL, &easyStruct, NULL, NULL);
}
else
{
PutStr(msgString);
}
}
/************************************************************************************/
static BOOL initiate(int argc, char **argv, CFState *cs)
{
CxObj *customObj;
memset(cs, 0, sizeof(CFState));
if (argc != 0)
{
struct RDArgs *rda;
IPTR args[] = { (IPTR) NULL, (IPTR) NULL, FALSE };
rda = ReadArgs(ARG_TEMPLATE, args, NULL);
if (rda != NULL)
{
if (args[ARG_PRI] != (IPTR) NULL)
{
nb.nb_Pri = *(LONG *)args[ARG_PRI];
}
getQualifier((STRPTR)args[ARG_QUALIFIER]);
if (args[ARG_CLICKS] != (IPTR) NULL)
{
cfInfo.ci_clicksToDo = *(LONG *)args[ARG_CLICKS];
}
}
FreeArgs(rda);
}
else
{
D(bug("Cli() == NULL\n"));
UBYTE **array = ArgArrayInit(argc, (UBYTE **)argv);
nb.nb_Pri = ArgInt(array, "CX_PRIORITY", 0);
cfInfo.ci_clicksToDo = ArgInt(array, "NUMCLICKS", 0);
D(bug("CLICKS in array from ArgArrayInit = %i\n",ArgInt(array,"NUMCLICKS", 0)));
getQualifier(ArgString(array, "QUALIFIER", NULL));
ArgArrayDone();
}
if (cfInfo.ci_clicksToDo == 0)
cfInfo.ci_clicksToDo = 2; /* Default value is 2 */
D(bug("CLICKS to do = %i\n",cfInfo.ci_clicksToDo));
nb.nb_Name = _(MSG_CLICK2FNT_CXNAME);
nb.nb_Title = _(MSG_CLICK2FNT_CXTITLE);
nb.nb_Descr = _(MSG_CLICK2FNT_CXDESCR);
cs->cs_msgPort = CreateMsgPort();
if (cs->cs_msgPort == NULL)
{
showSimpleMessage(_(MSG_CANT_CREATE_MSGPORT));
return FALSE;
}
nb.nb_Port = cs->cs_msgPort;
cs->cs_broker = CxBroker(&nb, 0);
if (cs->cs_broker == NULL)
{
return FALSE;
}
customObj = CxCustom(clicktoFront, 0);
if (customObj == NULL)
{
showSimpleMessage(_(MSG_CANT_CREATE_MSGPORT));
return FALSE;
}
AttachCxObj(cs->cs_broker, customObj);
ActivateCxObj(cs->cs_broker, TRUE);
cfInfo.ci_thisWindow = IntuitionBase->ActiveWindow;
inputIO = (struct IOStdReq *)CreateIORequest(cs->cs_msgPort,
sizeof(struct IOStdReq));
if (inputIO == NULL)
{
showSimpleMessage(_(MSG_CANT_ALLOCATE_MEM));
return FALSE;
}
if ((OpenDevice("input.device", 0, (struct IORequest *)inputIO, 0)) != 0)
{
showSimpleMessage(_(MSG_CANT_OPEN_INPUTDEVICE));
return FALSE;
}
InputBase = (struct Device *)inputIO->io_Device;
return TRUE;
}
/************************************************************************************/
static void getQualifier(STRPTR qualString)
{
if (qualString == NULL)
{
return;
}
if (strcmp("CTRL", qualString) == 0)
{
cfInfo.ci_qualifiers = IEQUALIFIER_CONTROL;
}
if (strcmp("LEFT_ALT", qualString) == 0)
{
cfInfo.ci_qualifiers = IEQUALIFIER_LALT;
}
if (strcmp("RIGHT_ALT", qualString) == 0)
{
cfInfo.ci_qualifiers = IEQUALIFIER_RALT;
}
/* Default is NONE */
}
/************************************************************************************/
static void freeResources(CFState *cs)
{
struct Message *cxm;
if (cs->cs_broker != NULL)
{
DeleteCxObjAll(cs->cs_broker);
}
if (cs->cs_msgPort != NULL)
{
while ((cxm = GetMsg(cs->cs_msgPort)))
{
ReplyMsg(cxm);
}
DeleteMsgPort(cs->cs_msgPort);
}
if (inputIO != NULL)
{
CloseDevice((struct IORequest *)inputIO);
DeleteIORequest((struct IORequest *)inputIO);
}
}
/************************************************************************************/
static void clicktoFront(CxMsg *cxm, CxObj *co)
{
/* NOTE! Should use arbitration for IntuitionBase... */
struct InputEvent *ie = (struct InputEvent *)CxMsgData(cxm);
if (ie->ie_Class == IECLASS_RAWMOUSE)
{
if (ie->ie_Code == SELECTDOWN)
{
struct Screen *screen;
struct Layer *layer;
/* Mask relvant qualifiers (key qualifiers) */
if ((PeekQualifier() & 0xff) != cfInfo.ci_qualifiers)
{
D(bug("Qualifiers: %i, Wanted qualifiers: %i\n",
(int)PeekQualifier(),
(int)cfInfo.ci_qualifiers | IEQUALIFIER_LEFTBUTTON));
return;
}
cfInfo.ci_lastWindow = cfInfo.ci_thisWindow;
if (IntuitionBase->ActiveWindow != NULL)
{
screen = IntuitionBase->ActiveWindow->WScreen;
}
else
{
screen = IntuitionBase->ActiveScreen;
}
layer = WhichLayer(&screen->LayerInfo,
screen->MouseX,
screen->MouseY);
if (layer == NULL)
{
return;
}
cfInfo.ci_thisWindow = (layer != NULL) ?
(struct Window *)layer->Window : NULL;
/*
Error: IB->ActiveWindow is non-NULL even if there is no
active window!
*/
if (layer->front != NULL)
{
/*
Counting clicks is only meaningfull if cfInfo.ci_clicksToDo
is no less than 2
*/
if (cfInfo.ci_clicksToDo > 1)
{
cfInfo.ci_clicksDone++;
D(bug("clicksDone = %i\n",cfInfo.ci_clicksDone));
/*
Return if the delay between two clicks is longer than
Input-Preferences-set double-click delay
*/
if (!DoubleClick(cfInfo.ci_lcSeconds,
cfInfo.ci_lcMicros,
ie->ie_TimeStamp.tv_secs,
ie->ie_TimeStamp.tv_micro))
{
cfInfo.ci_lcSeconds = ie->ie_TimeStamp.tv_secs;
cfInfo.ci_lcMicros = ie->ie_TimeStamp.tv_micro;
cfInfo.ci_clicksDone = 1L;
D(bug("DoubleClick is FALSE\nclicksDone = %i\n",
cfInfo.ci_clicksDone));
return;
}
D(bug("DoubleClick is TRUE\n"));
D(bug("Time %i %i, last time %i %i\n",
ie->ie_TimeStamp.tv_secs,
ie->ie_TimeStamp.tv_micro,
cfInfo.ci_lcSeconds,
cfInfo.ci_lcMicros));
cfInfo.ci_lcSeconds = ie->ie_TimeStamp.tv_secs;
cfInfo.ci_lcMicros = ie->ie_TimeStamp.tv_micro;
/* Return if the user didn't make enough clicks */
if (cfInfo.ci_clicksDone < cfInfo.ci_clicksToDo)
{
return;
}
/* Return if the clicks weren't made in the same window */
if (cfInfo.ci_lastWindow != cfInfo.ci_thisWindow)
{
cfInfo.ci_clicksDone = 1L;
D(bug("Window changed. clicksDone = %i\n",
cfInfo.ci_clicksDone));
return;
}
/*
If we didn't return yet, that means that all conditions
are good to bring the window to front, and it will be
done now. We just reset cfInfo.ci_clicksDone to 0 in
order to be ready for another bring-to-front loop...
*/
cfInfo.ci_clicksDone = 0L;
}/* if (cfInfo.ci_nbClicks) */
WindowToFront(cfInfo.ci_thisWindow);
if (cfInfo.ci_thisWindow != IntuitionBase->ActiveWindow)
{
ActivateWindow(cfInfo.ci_thisWindow);
}
D(bug("Window %s was put to front.\n",
cfInfo.ci_thisWindow->Title));
}
else
{
D(bug("New: %p Old: %p\n", cfInfo.ci_thisWindow,
IntuitionBase->ActiveWindow));
}
} /* if (ie->ie_Code == SELECTDOWN) */
} /* if (ie->ie_Class == IECLASS_RAWMOUSE) */
}
/************************************************************************************/
static void handleCx(CFState *cs)
{
CxMsg *msg;
BOOL quit = FALSE;
LONG signals;
while (!quit)
{
signals = Wait((1 << nb.nb_Port->mp_SigBit) | SIGBREAKF_CTRL_C);
if (signals & (1 << nb.nb_Port->mp_SigBit))
{
while ((msg = (CxMsg *)GetMsg(cs->cs_msgPort)))
{
switch (CxMsgType(msg))
{
case CXM_COMMAND:
switch (CxMsgID(msg))
{
case CXCMD_DISABLE:
ActivateCxObj(cs->cs_broker, FALSE);
break;
case CXCMD_ENABLE:
ActivateCxObj(cs->cs_broker, TRUE);
break;
case CXCMD_UNIQUE:
/* Running the program twice is the same as shutting
down the existing program... */
/* Fall through */
case CXCMD_KILL:
quit = TRUE;
break;
} /* switch (CxMsgID(msg)) */
break;
} /* switch (CxMsgType(msg))*/
ReplyMsg((struct Message *)msg);
} /* while ((msg = (CxMsg *)GetMsg(cs->cs_msgPort))) */
}
if (signals & SIGBREAKF_CTRL_C)
{
quit = TRUE;
}
} /* while(!quit) */
}
/************************************************************************************/
int main(int argc, char **argv)
{
CFState cState;
int error = RETURN_OK;
D((argc == 0) ? bug("argc == 0\n") : bug("argc != 0\n") );
if (initiate(argc, argv, &cState))
{
handleCx(&cState);
}
else
{
error = RETURN_FAIL;
}
freeResources(&cState);
return error;
}
/************************************************************************************/
ADD2INIT(Locale_Initialize, 90);
ADD2EXIT(Locale_Deinitialize, 90);
/* HotKey.c - Simple hot key commodity */
#include <exec/libraries.h>
#include <libraries/commodities.h>
#include <dos/dos.h>
#include <proto/exec.h>
#include <proto/commodities.h>
#define EVT_HOTKEY 1L
void main(int, char **);
void ProcessMsg(void);
struct Library *CxBase, *IconBase;
struct MsgPort *broker_mp;
CxObj *broker, *filter, *sender, *translate;
struct NewBroker newbroker = {
NB_VERSION,
"RKM HotKey", /* string to identify this broker */
"A Simple HotKey",
"A simple hot key commodity",
NBU_UNIQUE | NBU_NOTIFY, /* Don't want any new commodities starting with this name. */
0, 0, 0, 0 /* If someone tries it, let me know */
};
ULONG cxsigflag;
void main(int argc, char **argv)
{
UBYTE *hotkey, **ttypes;
CxMsg *msg;
if (CxBase = OpenLibrary("commodities.library", 37L))
{
/* open the icon.library for the support library */
/* functions, ArgArrayInit() and ArgArrayDone() */
if (IconBase = OpenLibrary("icon.library", 36L))
{
if (broker_mp = CreateMsgPort())
{
newbroker.nb_Port = broker_mp;
cxsigflag = 1L << broker_mp->mp_SigBit;
/* ArgArrayInit() is a support library function (from the 2.0 version
* of amiga.lib) that makes it easy to read arguments from either a
* CLI or from Workbench's ToolTypes. Because it uses icon.library,
* the library has to be open before calling this function.
* ArgArrayDone() cleans up after this function.
*/
ttypes = ArgArrayInit(argc, argv);
/* ArgInt() (also from amiga.lib) searches through the array set up
* by ArgArrayInit() for a specific ToolType. If it finds one, it
* returns the numeric value of the number that followed the
* ToolType (i.e., CX_PRIORITY=7). If it doesn't find the ToolType,
* it returns the default value (the third argument)
*/
newbroker.nb_Pri = (BYTE)ArgInt(ttypes, "CX_PRIORITY", 0);
/* ArgString() works just like ArgInt(), except it returns a pointer to a string
* rather than an integer. In the example below, if there is no ToolType
* "HOTKEY", the function returns a pointer to "rawkey control esc".
*/
hotkey = ArgString(ttypes, "HOTKEY", "rawkey control esc");
if (broker = CxBroker(&newbroker, NULL))
{
/* CxFilter() is a macro that creates a filter CxObject. This filter
* passes input events that match the string pointed to by hotkey.
*/
if (filter = CxFilter(hotkey))
{
/* Add a CxObject to another's personal list */
AttachCxObj(broker, filter);
/* CxSender() creates a sender CxObject. Every time a sender gets
* a CxMessage, it sends a new CxMessage to the port pointed to in
* the first argument. CxSender()'s second argument will be the ID
* of any CxMessages the sender sends to the port. The data pointer
* associated with the CxMessage will point to a *COPY* of the
* InputEvent structure associated with the original CxMessage.
*/
if (sender = CxSender(broker_mp, EVT_HOTKEY))
{
AttachCxObj(filter, sender);
/* CxTranslate() creates a translate CxObject. When a translate
* CxObject gets a CxMessage, it deletes the original CxMessage
* and adds a new input event to the input.device's input stream
* after the Commodities input handler. CxTranslate's argument
* points to an InputEvent structure from which to create the new
* input event. In this example, the pointer is NULL, meaning no
* new event should be introduced, which causes any event that
* reaches this object to disappear from the input stream.
*/
if (translate = (CxTranslate(NULL)))
{
AttachCxObj(filter, translate);
/* CxObjError() is a commodities.library function that returns
* the internal accumulated error code of a CxObject.
*/
if (! CxObjError(filter))
{
ActivateCxObj(broker, 1L);
ProcessMsg();
}
}
}
}
/* DeleteCxObjAll() is a commodities.library function that not only
* deletes the CxObject pointed to in its argument, but it deletes
* all of the CxObjects that are attached to it.
*/
DeleteCxObjAll(broker);
/* Empty the port of all CxMsgs */
while(msg = (CxMsg *)GetMsg(broker_mp))
ReplyMsg((struct Message *)msg);
}
DeletePort(broker_mp);
}
/* this amiga.lib function cleans up after ArgArrayInit() */
ArgArrayDone();
CloseLibrary(IconBase);
}
CloseLibrary(CxBase);
}
}
void ProcessMsg(void)
{
extern struct MsgPort *broker_mp;
extern CxObj *broker;
extern ULONG cxsigflag;
CxMsg *msg;
ULONG sigrcvd, msgid, msgtype;
LONG returnvalue = 1L;
while(returnvalue)
{
sigrcvd = Wait(SIGBREAKF_CTRL_C | cxsigflag);
while(msg = (CxMsg *)GetMsg(broker_mp))
{
msgid = CxMsgID(msg);
msgtype = CxMsgType(msg);
ReplyMsg((struct Message *)msg);
switch(msgtype)
{
case CXM_IEVENT:
printf("A CXM_EVENT, ");
switch(msgid)
{
case EVT_HOTKEY: /* We got the message from the sender CxObject */
printf("You hit the HotKey.\n");
break;
default:
printf("unknown.\n");
break;
}
break;
case CXM_COMMAND:
printf("A command: ");
switch(msgid)
{
case CXCMD_DISABLE:
printf("CXCMD_DISABLE\n");
ActivateCxObj(broker, 0L);
break;
case CXCMD_ENABLE:
printf("CXCMD_ENABLE\n");
ActivateCxObj(broker, 1L);
break;
case CXCMD_KILL:
printf("CXCMD_KILL\n");
returnvalue = 0L;
break;
case CXCMD_UNIQUE:
/* Commodities Exchange can be told not only to refuse to launch a
* commodity with a name already in use but also can notify the
* already running commodity that it happened. It does this by
* sending a CXM_COMMAND with the ID set to CXMCMD_UNIQUE. If the
* user tries to run a windowless commodity that is already running,
* the user wants the commodity to shut down. */
printf("CXCMD_UNIQUE\n");
returnvalue = 0L;
break;
default:
printf("Unknown msgid\n");
break;
}
break;
default:
printf("Unknown msgtype\n");
break;
}
}
if (sigrcvd & SIGBREAKF_CTRL_C)
{
returnvalue = 0L;
printf("CTRL C signal break\n");
}
}
}
CxObj *CreateCxObj(ULONG type, IPTR arg1, IPTR arg2) CxObj *CxBroker(struct NewBroker *nb, LONG *error) LONG ActivateCxObj(CxObj *co, LONG true) void DeleteCxObj(CxObj *co) void DeleteCxObjAll(CxObj *co) ULONG CxObjType(CxObj *co) LONG CxObjError(CxObj *co) void ClearCxObjError(CxObj *co) LONG SetCxObjPri(CxObj *co, LONG pri) void AttachCxObj(CxObj *headObj, CxObj *co) void EnqueueCxObj(CxObj *headObj, CxObj *co) void InsertCxObj(CxObj *headObj, CxObj *co, CxObj *pred) void RemoveCxObj(CxObj *co) void SetTranslate(CxObj *translator, struct InputEvent *events) void SetFilter(CxObj *filter, STRPTR text) void SetFilterIX(CxObj *filter, IX *ix) LONG ParseIX(CONST_STRPTR desc, IX *ix) ULONG CxMsgType(CxMsg *cxm) APTR CxMsgData(CxMsg *cxm) LONG CxMsgID(CxMsg *cxm) void DivertCxMsg(CxMsg *cxm, CxObj *headObj, CxObj *returnObj) void RouteCxMsg(CxMsg *cxm, CxObj *co) void DisposeCxMsg(CxMsg *cxm) BOOL InvertKeyMap(ULONG ansiCode, struct InputEvent *event, struct KeyMap *km) void AddIEvents(struct InputEvent *events) LONG CopyBrokerList(struct List *CopyofList) void FreeBrokerList(struct List *brokerList) ULONG BrokerCommand(STRPTR name, ULONG command) BOOL MatchIX(struct InputEvent *event, IX *ix)
struct NewBroker { BYTE nb_Version; BYTE nb_Pad; APTR nb_Name; APTR nb_Title; APTR nb_Descr; SHORT nb_Unique; WORD nb_Flags; BYTE nb_Pri; BYTE nb_Pad2; APTR nb_Port; WORD nb_ReservedChannel; };
标志
NBU_NOTIFY COF_SHOW_HIDE CX_INVALID CX_FILTER CX_TYPEFILTER CX_SEND CX_SIGNAL CX_TRANSLATE CX_BROKER CX_DEBUG CX_CUSTOM CX_ZERO CXM_UNIQUE CXM_IEVENT CXM_COMMAND CXCMD_DISABLE CXCMD_ENABLE CXCMD_APPEAR CXCMD_DISAPPEAR CXCMD_KILL CXCMD_UNIQUE CXCMD_LIST_CHG
CMDE_OK CMDE_NOBROKER CMDE_NOPORT CMDE_NOMEM
COERR_ISNULL COERR_NULLATTACH COERR_BADFILTER COERR_BADTYPE
struct IX { UBYTE ix_Version; UBYTE ix_Class; UWORD ix_Code; UWORD ix_CodeMask; UWORD ix_Qualifier; UWORD ix_QualMask; UWORD ix_QualSame; ];
IX 和 QualMask 的标志
IXSYM_SHIFT IXSYM_CAPS IXSYM_ALT IXSYM_SHIFTMASK IXSYM_CAPSMASK IXSYM_ALTMASK IX_NORMALQUALS