This repository has been archived on 2024-04-08. You can view files and clone it, but cannot push or open issues or pull requests.
magicka/deps/cdk-5.0-20161210/binding.c

231 lines
5.1 KiB
C
Raw Normal View History

#include <cdk_int.h>
/*
* $Author: tom $
* $Date: 2011/05/16 22:36:08 $
* $Revision: 1.56 $
*
* Notes:
*
* The cdktype parameter passed to bindCDKObject, etc., is redundant since
* the object parameter also has the same information. For compatibility
* just use it for a sanity check.
*/
#ifndef KEY_MAX
#define KEY_MAX 512
#endif
static CDKOBJS *bindableObject (EObjectType * cdktype, void *object)
{
CDKOBJS *obj = (CDKOBJS *)object;
if (obj != 0 && *cdktype == ObjTypeOf (obj))
{
if (*cdktype == vFSELECT)
{
*cdktype = vENTRY;
object = ((CDKFSELECT *)object)->entryField;
}
else if (*cdktype == vALPHALIST)
{
*cdktype = vENTRY;
object = ((CDKALPHALIST *)object)->entryField;
}
}
else
{
object = 0;
}
return (CDKOBJS *)object;
}
/*
* This inserts a binding.
*/
void bindCDKObject (EObjectType cdktype,
void *object,
chtype key,
BINDFN function,
void *data)
{
CDKOBJS *obj = bindableObject (&cdktype, object);
if ((key < KEY_MAX) && obj != 0)
{
if (key != 0 && (unsigned)key >= obj->bindingCount)
{
unsigned next = (unsigned) (key + 1);
if (obj->bindingList != 0)
obj->bindingList = typeReallocN (CDKBINDING, obj->bindingList, next);
else
obj->bindingList = typeMallocN (CDKBINDING, next);
memset (&(obj->bindingList[obj->bindingCount]), 0,
(next - obj->bindingCount) * sizeof (CDKBINDING));
obj->bindingCount = next;
}
if (obj->bindingList != 0)
{
obj->bindingList[key].bindFunction = function;
obj->bindingList[key].bindData = data;
}
}
}
/*
* This removes a binding on an object.
*/
void unbindCDKObject (EObjectType cdktype, void *object, chtype key)
{
CDKOBJS *obj = bindableObject (&cdktype, object);
if (obj != 0 && ((unsigned)key < obj->bindingCount))
{
obj->bindingList[key].bindFunction = 0;
obj->bindingList[key].bindData = 0;
}
}
/*
* This removes all the bindings for the given objects.
*/
void cleanCDKObjectBindings (EObjectType cdktype, void *object)
{
CDKOBJS *obj = bindableObject (&cdktype, object);
if (obj != 0 && obj->bindingList != 0)
{
unsigned x;
for (x = 0; x < obj->bindingCount; x++)
{
(obj)->bindingList[x].bindFunction = 0;
(obj)->bindingList[x].bindData = 0;
}
freeAndNull ((obj)->bindingList);
}
}
/*
* This checks to see if the binding for the key exists:
* If it does then it runs the command and returns its value, normally TRUE.
* If it doesn't it returns a FALSE. This way we can 'overwrite' coded
* bindings.
*/
int checkCDKObjectBind (EObjectType cdktype, void *object, chtype key)
{
CDKOBJS *obj = bindableObject (&cdktype, object);
if (obj != 0 && ((unsigned)key < obj->bindingCount))
{
if ((obj)->bindingList[key].bindFunction != 0)
{
BINDFN function = obj->bindingList[key].bindFunction;
void *data = obj->bindingList[key].bindData;
return function (cdktype, object, data, key);
}
}
return (FALSE);
}
/*
* This checks to see if the binding for the key exists.
*/
bool isCDKObjectBind (EObjectType cdktype, void *object, chtype key)
{
bool result = FALSE;
CDKOBJS *obj = bindableObject (&cdktype, object);
if (obj != 0 && ((unsigned)key < obj->bindingCount))
{
if ((obj)->bindingList[key].bindFunction != 0)
result = TRUE;
}
return (result);
}
/*
* This is a dummy function used to ensure that the constant for mapping has
* a distinct address.
*/
int getcCDKBind (EObjectType cdktype GCC_UNUSED,
void *object GCC_UNUSED,
void *clientData GCC_UNUSED,
chtype input GCC_UNUSED)
{
return 0;
}
/*
* Read from the input window, filtering keycodes as needed.
*/
int getcCDKObject (CDKOBJS *obj)
{
EObjectType cdktype = ObjTypeOf (obj);
CDKOBJS *test = bindableObject (&cdktype, obj);
int result = wgetch (InputWindowOf (obj));
if (result >= 0
&& test != 0
&& (unsigned)result < test->bindingCount
&& test->bindingList[result].bindFunction == getcCDKBind)
{
result = (int)(long)test->bindingList[result].bindData;
}
else if (test == 0
|| (unsigned)result >= test->bindingCount
|| test->bindingList[result].bindFunction == 0)
{
switch (result)
{
case '\r':
case '\n':
result = KEY_ENTER;
break;
case '\t':
result = KEY_TAB;
break;
case DELETE:
result = KEY_DC;
break;
case '\b': /* same as CTRL('H'), for ASCII */
result = KEY_BACKSPACE;
break;
case CDK_BEGOFLINE:
result = KEY_HOME;
break;
case CDK_ENDOFLINE:
result = KEY_END;
break;
case CDK_FORCHAR:
result = KEY_RIGHT;
break;
case CDK_BACKCHAR:
result = KEY_LEFT;
break;
case CDK_NEXT:
result = KEY_TAB;
break;
case CDK_PREV:
result = KEY_BTAB;
break;
}
}
return result;
}
/*
* Use this function rather than getcCDKObject(), since we can extend it to
* handle wide-characters.
*/
int getchCDKObject (CDKOBJS *obj, boolean *functionKey)
{
int key = getcCDKObject (obj);
*functionKey = (key >= KEY_MIN && key <= KEY_MAX);
return key;
}