-
Notifications
You must be signed in to change notification settings - Fork 0
/
hotkey.c
237 lines (207 loc) · 6.51 KB
/
hotkey.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
//#define HDEBUG
#include "dockybase.h"
#include "KeyMapSwitcher_rev.h"
#define CATCOMP_NUMBERS
#define CATCOMP_BLOCK
//#define CATCOMP_CODE
#include "include/keymapswitcher_strings.h"
extern struct LocaleInfo li;
//extern char textbuf[150]; // for localized messages
extern struct ExecIFace *IExec;
extern struct DOSIFace *IDOS;
extern struct UtilityIFace *IUtility;
extern struct CommoditiesIFace *ICommodities;
extern void DoMessage(char *message, char reqtype, struct DockyData *dd);
extern void LoadImageFlag(struct DockyData *dd);
extern BOOL ChangeKeymap(struct DockyData *dd, STRPTR keymap);
extern void SignalDocky(struct DockyData *dd, uint32 flags);
BOOL ProcessMsg(struct DockyData *dd);
int32 OpenCX(CONST_STRPTR args, LONG length, struct ExecBase *sysbase);
extern BOOL KM3;
#define CXIE_HOTKEY 1L
struct MsgPort *cxBrokerMP = NULL;
CxObj *cxBroker = NULL,
*filter = NULL, // for hotkey1
*sender = NULL,
*translate = NULL;
struct NewBroker cxNewbroker = { NB_VERSION,
"KeymapSwitcher",
LIBNAME,//VERS,
NULL, // Description (set/localized later)
NBU_UNIQUE|NBU_NOTIFY,
COF_CONSTANT, // don't exit/end from within Exchange
0, 0, 0 };
ULONG cxsigflag = 0;
BOOL OpenCX_NP(struct DockyIFace *Self, struct DockyData *dd)
{
struct DockyBase *processDockyBase;
// Open the library for the use of the process
// so it doesn't get expunged while the process is starting
if( (processDockyBase=(struct DockyBase *)IExec->OpenLibrary(LIBNAME, VERSION)) )
{
Self->Obtain();
if( (dd->CxProc=IDOS->CreateNewProcTags(
NP_Entry, OpenCX,
NP_Name, LIBNAME,
NP_Child, TRUE,
NP_EntryData, Self,
NP_StackSize, 16384,
NP_ProgramDir, IDOS->Lock(dd->filepath, SHARED_LOCK), // for Exchange VERSION & WBINFO
//NP_NotifyOnDeathSigTask, dd->attn.amidockTask,
//NP_NotifyOnDeathSignalBit, dd->attn.attentionSignalBit,
#ifdef HDEBUG
NP_Output, IDOS->Open("CON:20/20/600/150/KMS_cx",MODE_OLDFILE),
#endif
NP_FinalCode, IExec->CloseLibrary,
NP_FinalData, processDockyBase,
TAG_DONE)) )
{
#ifdef HDEBUG
IDOS->Printf("NewProcess CREATED (CX=0x%lx)\n",dd->CxProc);
#endif
return TRUE;
}
Self->Release();
IExec->CloseLibrary( (struct Library *)processDockyBase );
}
#ifdef HDEBUG
IDOS->Printf("NewProcess FAILED (CX=0x%lx)\n",dd->CxProc);
#endif
return FALSE;
}
int32 OpenCX(CONST_STRPTR args, LONG length, struct ExecBase *sysbase)
{
struct ExecIFace *iexec = (struct ExecIFace *)sysbase->MainInterface;
struct Process *me = (struct Process *)iexec->FindTask(NULL);
struct DockyIFace *Self = (struct DockyIFace *)me->pr_EntryData;
struct DockyData *dd = (struct DockyData *)((uint32)Self - Self->Data.NegativeSize);
CxMsg *msg;
if( (cxBrokerMP=IExec->AllocSysObjectTags(ASOT_PORT, ASOPORT_Name,LIBNAME"_port", TAG_DONE)) != NULL)
{
cxNewbroker.nb_Descr = GetString(&li, MSG_COMMODITY_DESC);
cxNewbroker.nb_Port = cxBrokerMP;
cxsigflag = 1L << cxBrokerMP->mp_SigBit;
if( (cxBroker=ICommodities->CxBroker(&cxNewbroker, NULL)) )
{
filter = CxFilter(dd->hotkey1); // hotkey to swap keymaps
if( ICommodities->CxObjError(filter) )
{// Invalid hotkey -> set default hotkey to swap keymaps
DoMessage( (STRPTR)GetString(&li, MSG_COMMODITY_HK1_INVALID), REQIMAGE_ERROR, dd );
IUtility->Strlcpy( dd->hotkey1, "ALT ESC", sizeof(dd->hotkey1) );
filter = CxFilter(dd->hotkey1);
}
ICommodities->AttachCxObj(cxBroker, filter);
sender = CxSender(cxBrokerMP, CXIE_HOTKEY);
ICommodities->AttachCxObj(filter, sender);
if( (translate=CxTranslate(NULL)) )
ICommodities->AttachCxObj(filter, translate);
ICommodities->ActivateCxObj(cxBroker, TRUE);
while( ProcessMsg(dd) );
ICommodities->DeleteCxObjAll(cxBroker);
// Empty the port of all CxMsgs
while( (msg=(CxMsg *)IExec->GetMsg(cxBrokerMP)) )
IExec->ReplyMsg( (struct Message *)msg );
}
IExec->FreeSysObject(ASOT_PORT, cxBrokerMP);
}
#ifdef HDEBUG
IDOS->Delay(150);
#endif
Self->Release();
dd->CxProc = NULL;
//IExec->DebugPrintF("[%s]OpenCX cx=0x%lX\n",LIBNAME,dd->CxProc);
return( (int32)iexec );
}
BOOL ProcessMsg(struct DockyData *dd)
{
CxMsg *msg;
uint32 sigrcvd, msgid, msgtype;
BOOL CXcontinue = TRUE;
sigrcvd = IExec->Wait(SIGBREAKF_CTRL_C|cxsigflag);
if( (msg=(CxMsg *)IExec->GetMsg(cxBrokerMP)) )
{
msgid = ICommodities->CxMsgID(msg);
msgtype = ICommodities->CxMsgType(msg);
IExec->ReplyMsg( (struct Message *)msg );
switch(msgtype)
{
case CXM_IEVENT:
#ifdef HDEBUG
IDOS->Printf("A CXM_EVENT, ");
#endif
switch(msgid)
{
case CXIE_HOTKEY: // we got the message from the sender CxObject
#ifdef HDEBUG
IDOS->Printf("You hit the HOTKEY!\n");
#endif
if( dd->km_pos==3 || (dd->km_pos==2 && !KM3) )
dd->km_pos = 0;
if( ChangeKeymap(dd, dd->KeymapName[dd->km_pos]) )
{
IUtility->Strlcpy( dd->keymapSel, dd->KeymapName[dd->km_pos], sizeof(dd->keymapSel) );
dd->km_pos++; // points to next possible KeymapName[]
LoadImageFlag(dd); // (re)load new image/flag after user choosed new
SignalDocky(dd, 1); // need to 'RedrawNow'
}
break;
default:
#ifdef HDEBUG
IDOS->Printf("???? msgid\n");
#endif
break;
}
break;
case CXM_COMMAND:
#ifdef HDEBUG
IDOS->Printf("CXM_COMMAND: ");
#endif
switch(msgid)
{
case CXCMD_DISABLE:
#ifdef HDEBUG
IDOS->Printf("CXCMD_DISABLE\n");
#endif
ICommodities->ActivateCxObj(cxBroker, FALSE);
break;
case CXCMD_ENABLE:
#ifdef HDEBUG
IDOS->Printf("CXCMD_ENABLE\n");
#endif
ICommodities->ActivateCxObj(cxBroker, TRUE);
break;
case CXCMD_KILL:
#ifdef HDEBUG
IDOS->Printf("CXCMD_KILL\n");
#endif
CXcontinue = FALSE;
break;
case CXCMD_UNIQUE:
#ifdef HDEBUG
IDOS->Printf("CXCMD_UNIQUE\n");
#endif
CXcontinue = FALSE;
break;
default:
#ifdef HDEBUG
IDOS->Printf("???? msgid\n");
#endif
break;
}
break;
default:
#ifdef HDEBUG
IDOS->Printf("???? msgtype\n");
#endif
break;
}
}
if(sigrcvd & SIGBREAKF_CTRL_C)
{
CXcontinue = FALSE;
#ifdef HDEBUG
IDOS->Printf("CTRL+C signal break\n");
#endif
}
return(CXcontinue);
}