aboutsummaryrefslogtreecommitdiffstats
path: root/cphidgetmacros.h
blob: f228c9cfbc116665ccab4173d4554d84494e737e (plain)
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
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
#ifndef _CPHIDGET_MACROS
#define _CPHIDGET_MACROS

#define PHANDLE(pname) CPhidget##pname##Handle 

#define DPHANDLE(pname) typedef struct _CPhidget##pname *CPhidget##pname##Handle; /**< A Phidget pname handle*/

//Regular Versions
#define CHDRSTANDARD(pname) \
/** Creates a Phidget pname handle. @param phid A pointer to an unallocated Phidget pname handle. */ \
PHIDGET21_API int CCONV CPhidget##pname##_create(CPhidget##pname##Handle *phid);

#define CHDREVENTINDEX(pname,param,...) PHIDGET21_API int CCONV CPhidget##pname##_set_On##param##_Handler(PHANDLE(pname) phid, int (CCONV *fptr)(PHANDLE(pname) phid, void *userPtr, int index, __VA_ARGS__), void *userPtr);
#define CHDREVENT(pname,param,...) PHIDGET21_API int CCONV CPhidget##pname##_set_On##param##_Handler(PHANDLE(pname) phid, int (CCONV *fptr)(PHANDLE(pname) phid, void *userPtr, __VA_ARGS__), void *userPtr);

#define CHDRGET(pname,propname,...) PHIDGET21_API int CCONV CPhidget##pname##_get##propname(PHANDLE(pname) phid, __VA_ARGS__); 
#define CHDRSET(pname,propname,...) PHIDGET21_API int CCONV CPhidget##pname##_set##propname(PHANDLE(pname) phid, __VA_ARGS__); 

#define CHDRGETINDEX(pname,propname,...) PHIDGET21_API int CCONV CPhidget##pname##_get##propname(PHANDLE(pname) phid, int index, __VA_ARGS__); 
#define CHDRSETINDEX(pname,propname,...) PHIDGET21_API int CCONV CPhidget##pname##_set##propname(PHANDLE(pname) phid, int index, __VA_ARGS__); 

//Versions for Deprecation

#define DEP_CHDREVENTINDEX(depmsg,pname,param,...) DEPRECATE_WIN(depmsg) PHIDGET21_API int CCONV CPhidget##pname##_set_On##param##_Handler(PHANDLE(pname), int (CCONV *fptr)(PHANDLE(pname), void *userPtr, int index, __VA_ARGS__), void *userPtr) DEPRECATE_GCC ;
#define DEP_CHDREVENT(depmsg,pname,param,...) DEPRECATE_WIN(depmsg) PHIDGET21_API int CCONV CPhidget##pname##_set_On##param##_Handler(PHANDLE(pname), int (CCONV *fptr)(PHANDLE(pname), void *userPtr, __VA_ARGS__), void *userPtr) DEPRECATE_GCC ;

#define DEP_CHDRGET(depmsg,pname,propname,...) DEPRECATE_WIN(depmsg) PHIDGET21_API int CCONV CPhidget##pname##_get##propname(PHANDLE(pname),__VA_ARGS__) DEPRECATE_GCC ;
#define DEP_CHDRSET(depmsg,pname,propname,...) DEPRECATE_WIN(depmsg) PHIDGET21_API int CCONV CPhidget##pname##_set##propname(PHANDLE(pname), __VA_ARGS__) DEPRECATE_GCC ; 

#define DEP_CHDRGETINDEX(depmsg,pname,propname,...) DEPRECATE_WIN(depmsg) PHIDGET21_API int CCONV CPhidget##pname##_get##propname(PHANDLE(pname), int index, __VA_ARGS__) DEPRECATE_GCC ; 
#define DEP_CHDRSETINDEX(depmsg,pname,propname,...) DEPRECATE_WIN(depmsg) PHIDGET21_API int CCONV CPhidget##pname##_set##propname(PHANDLE(pname), int index, __VA_ARGS__) DEPRECATE_GCC ; 


#define TESTPTR(phidname) if (!phidname) return EPHIDGET_INVALIDARG;
#define TESTPTRS(vname1,vname2) if ((!vname1) || (!vname2)) return EPHIDGET_INVALIDARG;
#define TESTINDEX(vname1) if (Index >= phid->vname1 || Index < 0) return EPHIDGET_OUTOFBOUNDS;
#define TESTMASGN(vname1, check) if(phid->vname1 == check) { *pVal = check; return EPHIDGET_UNKNOWNVAL; }
#define TESTRANGE(min, max) if(newVal < (min) || newVal > (max)) return EPHIDGET_INVALIDARG;
#define TESTDEVICETYPE(def) if (phid->phid.deviceID != def)	return EPHIDGET_WRONGDEVICE;
#define TESTATTACHED if (!CPhidget_statusFlagIsSet(phid->phid.status, PHIDGET_ATTACHED_FLAG)) return EPHIDGET_NOTATTACHED;
#define MASGN(vname1) { *pVal = phid->vname1; return EPHIDGET_OK; }

#define CFHANDLE(pname,param, ...) \
PHIDGET21_API int CCONV CPhidget##pname##_set_On##param##_Handler(CPhidget##pname##Handle phidA, int (CCONV *fptr)(CPhidget##pname##Handle, void *userPtr, __VA_ARGS__ ), void *userPtr) \
{ \
	CPhidget##pname##Info *phid = (CPhidget##pname##Info *)phidA; \
	TESTPTR(phid); \
	phid->fptr##param = fptr; \
	phid->fptr##param##ptr = userPtr; \
	return EPHIDGET_OK; \
}

#define CPHIDGETDATA(pname) static int CPhidget##pname##_dataInput(CPhidgetHandle phidG, unsigned char *buffer, int length) \
{ \
	CPhidget##pname##Handle phid = (CPhidget##pname##Handle)phidG; 

#define FIRE(ename, ...) \
if (phid->fptr##ename) \
	if(CPhidget_statusFlagIsSet(phid->phid.status, PHIDGET_ATTACHED_FLAG)) \
		phid->fptr##ename(phid, phid->fptr##ename##ptr, __VA_ARGS__)

#define QUEUE_ERROR_EVENT(ecode, buf) \
else \
{ \
	void **args = malloc(sizeof(void *)*2); \
	if(args) \
	{ \
		args[0] = strdup(buf); \
		args[1] = (void *)(size_t)ecode; \
		if(args[0]) \
		{ \
			if(CList_addToList((CListHandle *)&((CPhidgetHandle)phid)->errEventList, args, CPhidgetHandle_areEqual)!=EPHIDGET_OK) \
			{ \
				free(args[0]); \
				free(args); \
			} \
		} \
		else \
			free(args); \
	} \
}

#define FIRE_ERROR_BUF_INT(ecode, buf) \
if(CPhidget_statusFlagIsSet(((CPhidgetHandle)phid)->status, PHIDGET_ATTACHED_FLAG)) \
{ \
	if (((CPhidgetHandle)phid)->fptrError) \
		((CPhidgetHandle)phid)->fptrError((CPhidgetHandle)phid, ((CPhidgetHandle)phid)->fptrErrorptr, ecode, buf); \
} \

#define FIRE_ERROR_BUF(ecode, buf) \
FIRE_ERROR_BUF_INT(ecode, buf) \
QUEUE_ERROR_EVENT(ecode, buf)

#define FIRE_ERROR(ecode, ...) \
snprintf(error_buffer,sizeof(error_buffer), __VA_ARGS__); \
FIRE_ERROR_BUF_INT(ecode, error_buffer) \
QUEUE_ERROR_EVENT(ecode, error_buffer)

#define FIRE_ERROR_NOQUEUE(ecode, ...) \
snprintf(error_buffer,sizeof(error_buffer), __VA_ARGS__); \
FIRE_ERROR_BUF_INT(ecode, error_buffer)

#define CGETINDEX(pname,propname,proptype) \
PHIDGET21_API int CCONV CPhidget##pname##_get##propname(CPhidget##pname##Handle phid, int Index, proptype *pVal) { 

#define CGET(pname,propname,proptype) \
PHIDGET21_API int CCONV CPhidget##pname##_get##propname(CPhidget##pname##Handle phid, proptype *pVal) {

#define CSETINDEX(pname,propname,proptype) \
PHIDGET21_API int CCONV CPhidget##pname##_set##propname(CPhidget##pname##Handle phid, int Index, proptype newVal) { 

#define CSET(pname,propname,proptype) \
PHIDGET21_API int CCONV CPhidget##pname##_set##propname(CPhidget##pname##Handle phid, proptype newVal) { 

#define CPHIDGETCLEARVARS(pname) \
static int CPhidget##pname##_clearVars(CPhidgetHandle phidG) \
{ \
	CPhidget##pname##Handle phid = (CPhidget##pname##Handle)phidG; 

#define CPHIDGETINIT(pname) \
static int CPhidget##pname##_initAfterOpen(CPhidgetHandle phidG) \
{ \
	CPhidget##pname##Handle phid = (CPhidget##pname##Handle)phidG; 

#define CPHIDGETINITEVENTS(pname) \
static int CPhidget##pname##_eventsAfterOpen(CPhidgetHandle phidG) \
{ \
	CPhidget##pname##Handle phid = (CPhidget##pname##Handle)phidG; \
	int i = 0; \
	CListHandle traverse = phidG->errEventList; \
	for (; traverse; traverse = traverse->next) { \
		if (phidG->fptrError) \
			phidG->fptrError(phidG, phidG->fptrErrorptr, (int)*(int *)(&((void **)traverse->element)[1]), (char *)((void **)traverse->element)[0]); \
	} \
	CList_emptyList((CListHandle *)&phidG->errEventList, PTRUE, CPhidgetErrorEvent_free); \
	i = 0;

#define CSENDPACKET_BUF(pname) \
static int CPhidget##pname##_sendpacket(CPhidget##pname##Handle phid, \
    const unsigned char *buf) \
{ \
	int waitReturn; \
	TESTPTRS(phid, buf) \
again: \
	if (!CPhidget_statusFlagIsSet(phid->phid.status, PHIDGET_ATTACHED_FLAG)) \
		return EPHIDGET_NOTATTACHED; \
	CThread_mutex_lock(&phid->phid.outputLock); \
	if (phid->outputPacketLen) { \
		CThread_mutex_unlock(&phid->phid.outputLock); \
		waitReturn = CThread_wait_on_event(&phid->phid.writtenEvent, 1500); \
		switch(waitReturn) \
		{ \
		case WAIT_OBJECT_0: \
			break; \
		case WAIT_ABANDONED: \
			return EPHIDGET_UNEXPECTED; \
		case WAIT_TIMEOUT: \
			return EPHIDGET_TIMEOUT; \
		} \
		goto again; \
	} \
	memcpy(phid->outputPacket, buf, phid->phid.outputReportByteLength); \
	phid->outputPacketLen = phid->phid.outputReportByteLength; \
	CThread_reset_event(&phid->phid.writtenEvent); \
	CThread_mutex_unlock(&phid->phid.outputLock); \
	CThread_set_event(&phid->phid.writeAvailableEvent); \
	return 0; \
}

#define CMAKEPACKET(pname) \
static int CPhidget##pname##_makePacket(CPhidget##pname##Handle phid, \
    unsigned char *buffer) \
{

#define SENDPACKET(pname, propname) \
	do{ \
		unsigned char *buffer; \
		int ret = 0; \
		if(!(buffer = malloc(phid->phid.outputReportByteLength))) return EPHIDGET_NOMEMORY; \
		ZEROMEM(buffer, phid->phid.outputReportByteLength); \
		CThread_mutex_lock(&phid->phid.writelock); \
		phid->propname = newVal; \
		if((ret = CPhidget##pname##_makePacket(phid, buffer))) goto done; \
		if((ret = CPhidget##pname##_sendpacket(phid, buffer))) goto done; \
done: \
		CThread_mutex_unlock(&phid->phid.writelock); \
		free(buffer); \
		if(ret) return ret; \
	}while(0)

#define CMAKEPACKETINDEXED(pname) \
static int CPhidget##pname##_makePacket(CPhidget##pname##Handle phid, \
    unsigned char *buffer, int Index) \
{

#define SENDPACKETINDEXED(pname, propname, index) \
	do{ \
		unsigned char *buffer; \
		int ret = 0; \
		if(!(buffer = malloc(phid->phid.outputReportByteLength))) return EPHIDGET_NOMEMORY; \
		ZEROMEM(buffer, phid->phid.outputReportByteLength); \
		CThread_mutex_lock(&phid->phid.writelock); \
		phid->propname = newVal; \
		if((ret = CPhidget##pname##_makePacket(phid, buffer, index))) goto done; \
		if((ret = CPhidget##pname##_sendpacket(phid, buffer))) goto done; \
done: \
		CThread_mutex_unlock(&phid->phid.writelock); \
		free(buffer); \
		if(ret) return ret; \
	}while(0)


#define CGETPACKET(pname) \
static int CPhidget##pname##_getPacket(CPhidgetHandle phidG, \
    unsigned char *buf, unsigned int *lenp) \
{ 

#define CGETPACKET_BUF(pname) \
static int CPhidget##pname##_getPacket(CPhidgetHandle phidG, \
    unsigned char *buf, unsigned int *lenp) \
{ \
	CPhidget##pname##Handle phid = (CPhidget##pname##Handle)phidG; \
	TESTPTRS(phid, buf) \
	TESTPTR(lenp) \
	CThread_mutex_lock(&phid->phid.outputLock); \
	if (*lenp < phid->outputPacketLen) { \
		CThread_mutex_unlock(&phid->phid.outputLock); \
		return EPHIDGET_INVALIDARG; \
	} \
	memcpy(buf, phid->outputPacket, *lenp = phid->outputPacketLen); \
	phid->outputPacketLen = 0; \
	CThread_mutex_unlock(&phid->phid.outputLock); \
	return EPHIDGET_OK; \
}

#define CCREATE_INT(pname,pdef) \
	CPhidget##pname##Handle phid; \
	TESTPTR(phidp) \
	if (!(phid = (CPhidget##pname##Handle)malloc(sizeof (*phid)))) \
		return EPHIDGET_NOMEMORY; \
	ZEROMEM(phid, sizeof(*phid)); \
	phid->phid.deviceID = pdef; \
	phid->phid.fptrInit = CPhidget##pname##_initAfterOpen; \
	phid->phid.fptrClear = CPhidget##pname##_clearVars; \
	phid->phid.fptrEvents = CPhidget##pname##_eventsAfterOpen; \
	phid->phid.fptrData = CPhidget##pname##_dataInput; \
	phid->phid.fptrGetPacket = CPhidget##pname##_getPacket; \
	CThread_mutex_init(&phid->phid.lock); \
	CThread_mutex_init(&phid->phid.openCloseLock); \
	CThread_mutex_init(&phid->phid.writelock); \
	CThread_mutex_init(&phid->phid.outputLock); \
	CPhidget_clearStatusFlag(&phid->phid.status, PHIDGET_ATTACHED_FLAG, &(&phid->phid)->lock); \
	CThread_create_event(&phid->phid.writeAvailableEvent); \
	CThread_create_event(&phid->phid.writtenEvent); \
	*phidp = phid;

#define CCREATE(pname,pdef) int CCONV CPhidget##pname##_create(CPhidget##pname##Handle *phidp) \
{ \
	CCREATE_INT(pname,pdef) \
	return EPHIDGET_OK; \
}

#define CCREATE_EXTRA(pname,pdef) int CCONV CPhidget##pname##_create(CPhidget##pname##Handle *phidp) \
{ \
	CCREATE_INT(pname,pdef)

#define ADDNETWORKKEYINDEXED(kname, valType, propname) \
do{ \
	char key[1024], val[1024]; \
	CThread_mutex_lock(&phid->phid.lock); \
	phid->propname[Index] = newVal; \
	if(!CPhidget_statusFlagIsSet(phid->phid.status, PHIDGET_SERVER_CONNECTED_FLAG)) { \
		CThread_mutex_unlock(&phid->phid.lock); \
		return EPHIDGET_NETWORK_NOTCONNECTED; } \
	snprintf(key, (unsigned int)sizeof(key), "/PCK/%s/%d/" #kname "/%d", phid->phid.deviceType, phid->phid.serialNumber, Index); \
	snprintf(val, (int)sizeof(val), valType, newVal); \
	pdc_async_set(phid->phid.networkInfo->server->pdcs, key, val, (int)strlen(val), PFALSE, internal_async_network_error_handler, &phid->phid); \
	CThread_mutex_unlock(&phid->phid.lock); \
}while(0)

#define ADDNETWORKKEY(kname, valType, propname) \
do{ \
	char key[1024], val[1024]; \
	CThread_mutex_lock(&phid->phid.lock); \
	phid->propname = newVal; \
	if(!CPhidget_statusFlagIsSet(phid->phid.status, PHIDGET_SERVER_CONNECTED_FLAG)) { \
		CThread_mutex_unlock(&phid->phid.lock); \
		return EPHIDGET_NETWORK_NOTCONNECTED; } \
	snprintf(key, sizeof(key), "/PCK/%s/%d/" #kname , phid->phid.deviceType, phid->phid.serialNumber); \
	snprintf(val, sizeof(val), valType, newVal); \
	pdc_async_set(phid->phid.networkInfo->server->pdcs, key, val, (int)strlen(val), PFALSE, internal_async_network_error_handler, &phid->phid); \
	CThread_mutex_unlock(&phid->phid.lock); \
}while(0)

/* used in csocketevents.c */
#define PWC_SETKEYS(pname) \
int phidget##pname##_set(CPhidgetHandle arg, const char *setThing, int index, const char *state, pdict_reason_t reason) \
{ \
	int ret = EPHIDGET_OK; \
	CPhidget##pname##Handle phid = (CPhidget##pname##Handle)arg;

#define GET_DOUBLE_VAL double value = strtod(state, NULL)
#define GET_INT_VAL int value = strtol(state, NULL, 10)
#define GET_INT64_VAL __int64 value = strtoll(state, NULL, 10)

#define INC_KEYCOUNT(var, unktype) if(phid->var == unktype) phid->phid.keyCount++;
#define KEYNAME(name) !strncmp(setThing, name, sizeof(name))
#define CHKINDEX(atr, def) (index < phid->phid.attr.atr?phid->phid.attr.atr:def)

#define PWC_BAD_SETTYPE(pname) \
	do { \
		ret = EPHIDGET_INVALIDARG; \
		LOG(PHIDGET_LOG_DEBUG,"Bad setType for " #pname ": %s", setThing); \
	}while(0)

#endif