Esempio n. 1
0
bool Cx_TextUtil::ReadTextFile(BYTE head[5], std::wstring& content, 
							   const std::wstring& filename, 
							   ULONG nLenLimitMB, UINT codepage)
{
	ZeroMemory(head, sizeof(BYTE) * 5);
	content.resize(0);
	
	bool bRet = false;
	HANDLE hFile = ::CreateFileW(filename.c_str(), 
		GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);

	if (INVALID_HANDLE_VALUE == hFile)
	{
		LOG_ERROR2(LOGHEAD L"IDS_OPEN_FAIL", 
			filename << L", " << GetSystemErrorString(GetLastError()));
	}
	else
	{
		DWORD dwLength = ::GetFileSize(hFile, NULL);
		HGLOBAL hBuffer = NULL;

		if (dwLength != INVALID_FILE_SIZE)
		{
			if (dwLength > nLenLimitMB * 1024L * 1024L)
			{
				LOG_WARNING2(LOGHEAD L"IDS_HUGE_FILE", 
					(dwLength / (1024.0*1024.0)) << L"MB, " << filename);
				dwLength = nLenLimitMB * 1024L * 1024L;
			}
			hBuffer = GlobalAlloc(GHND, dwLength + 8);
		}
		
		if (hBuffer != NULL)
		{
			LPBYTE pBuffer = (LPBYTE)GlobalLock(hBuffer);
			if (pBuffer != NULL)
			{
				DWORD dwBytesRead = 0;
				::ReadFile(hFile, pBuffer, dwLength, &dwBytesRead, NULL);
				if (dwBytesRead > 0)
				{
					CopyMemory(head, pBuffer, sizeof(BYTE) * min(5, dwBytesRead));
					bRet = GetFileContent(content, pBuffer, dwBytesRead, codepage);
					if (!bRet)
					{
						LOG_WARNING2(LOGHEAD L"IDS_NOT_ANSIFILE", filename);
					}
				}
				GlobalUnlock(hBuffer);
			}
			GlobalFree(hBuffer);
		}
		
		::CloseHandle(hFile);
	}

	return bRet;
}
Esempio n. 2
0
std::wstring Cx_StringTable::GetValue(const std::wstring& module, 
									  const std::wstring& id, bool* hasvalue)
{
	std::wstring value;

	GetValue(value, module, id);
	if (hasvalue)
	{
		*hasvalue = !value.empty();
	}
	if (value.empty())
	{
		LOG_WARNING2(LOGHEAD L"IDS_NO_STRVALUE", module + L":" + id);
	}

	return value;
}
Esempio n. 3
0
long Cx_StringTable::RegisterFile(const std::wstring& filename)
{
	Cx_Interface<Ix_ConfigXml> pIFFile(CLSID_ConfigXmlFile);
	if (pIFFile.IsNull())
	{
		return 0;
	}

	pIFFile->SetFileName(filename.c_str());
	LOG_DEBUG2(LOGHEAD L"IDS_LOAD_STRFILE", PathFindFileNameW(filename.c_str()));

	long count = 0;
	for (int i = 0; i < 99; i++)
	{
		CConfigIOSection sec (pIFFile->GetData()->GetSectionByIndex(NULL, L"module", i));
		ITEM item;

		item.file = pIFFile->GetData();
		item.group = sec;
		item.module = sec->GetString(L"name");

		if (item.module.empty())
			break;

		if (Find(item.module) == m_groups.end())
		{
			m_groups.push_back(item);
			count++;
		}
		else
		{
			LOG_WARNING2(LOGHEAD L"IDS_IGNORE_STRGROUP", item.module);
		}
	}

	return count;
}
Esempio n. 4
0
/**
 * Check Video parameters against allowed values and read EDID structure
 * to ensure compatibility with sink.
 * @param video video parameters
 */
static int api_CheckParamsVideo(videoParams_t * video)
{
	u8 errorCode = TRUE;
	hdmivsdb_t vsdb;
	dtd_t dtd;
	unsigned i = 0;
	shortVideoDesc_t svd;
	videoCapabilityDataBlock_t capability;
	int valid = FALSE;
	colorimetryDataBlock_t colorimetry;

	LOG_TRACE();
	colorimetryDataBlock_Reset(&colorimetry);
	shortVideoDesc_Reset(&svd);
	dtd_Fill(&dtd, 1, 60000);
	videoCapabilityDataBlock_Reset(&capability);

	if (videoParams_GetHdmi(video))
	{ /* HDMI mode */
		if (api_EdidHdmivsdb(&vsdb) == TRUE)
		{
			if (videoParams_GetColorResolution(video) == 10
					&& !hdmivsdb_GetDeepColor30(&vsdb))
			{
				error_Set(ERR_SINK_DOES_NOT_SUPPORT_30BIT_DC);
				printk("Sink does NOT support 30bits/pixel deep colour mode");
				errorCode = FALSE;
			}
			else if (videoParams_GetColorResolution(video) == 12
					&& !hdmivsdb_GetDeepColor36(&vsdb))
			{
				error_Set(ERR_SINK_DOES_NOT_SUPPORT_36BIT_DC);
				printk("Sink does NOT support 36bits/pixel deep colour mode");
				errorCode = FALSE;
			}
			else if (videoParams_GetColorResolution(video) == 16
					&& !hdmivsdb_GetDeepColor48(&vsdb))
			{
				error_Set(ERR_SINK_DOES_NOT_SUPPORT_48BIT_DC);
				printk("Sink does NOT support 48bits/pixel deep colour mode");
				errorCode = FALSE;
			}
			if (videoParams_GetEncodingOut(video) == YCC444
					&& !hdmivsdb_GetDeepColorY444(&vsdb))
			{
				error_Set(ERR_SINK_DOES_NOT_SUPPORT_YCC444_DC);
				printk("Sink does NOT support YCC444 in deep colour mode");
				errorCode = FALSE;
			}
			if (videoParams_GetTmdsClock(video) > 16500)
			{
				/*
				 * Sink must specify MaxTMDSClk when supports frequencies over 165MHz
				 * GetMaxTMDSClk() is TMDS clock / 5MHz and GetTmdsClock() returns [0.01MHz]
				 * so GetMaxTMDSClk() value must be multiplied by 500 in order to be compared
				 */
				if (videoParams_GetTmdsClock(video) > (hdmivsdb_GetMaxTmdsClk(
						&vsdb) * 500))
				{
					error_Set(ERR_SINK_DOES_NOT_SUPPORT_TMDS_CLOCK);
					LOG_WARNING2("Sink does not support TMDS clock", videoParams_GetTmdsClock(video));
					LOG_WARNING2("Maximum TMDS clock supported is", hdmivsdb_GetMaxTmdsClk(&vsdb) * 500);
					errorCode = FALSE;
				}
			}
		}
		else
		{
			error_Set(ERR_SINK_DOES_NOT_SUPPORT_HDMI);
			printk("Sink does not support HDMI");
			errorCode = FALSE;
		}
		/* video out encoding (YCC/RGB) */
		if (videoParams_GetEncodingOut(video) == YCC444
				&& !api_EdidSupportsYcc444())
		{
			error_Set(ERR_SINK_DOES_NOT_SUPPORT_YCC444_ENCODING);
			printk("Sink does NOT support YCC444 encoding");
			errorCode = FALSE;
		}
		else if (videoParams_GetEncodingOut(video) == YCC422
				&& !api_EdidSupportsYcc422())
		{
			error_Set(ERR_SINK_DOES_NOT_SUPPORT_YCC422_ENCODING);
			printk("Sink does NOT support YCC422 encoding");
			errorCode = FALSE;
		}
		/* check extended colorimetry data and if supported by sink */
		if (videoParams_GetColorimetry(video) == EXTENDED_COLORIMETRY)
		{
			if (api_EdidColorimetryDataBlock(&colorimetry) == TRUE)
			{
				if (!colorimetryDataBlock_SupportsXvYcc601(&colorimetry)
						&& videoParams_GetExtColorimetry(video) == 0)
				{
					error_Set(ERR_SINK_DOES_NOT_SUPPORT_XVYCC601_COLORIMETRY);
					printk("Sink does NOT support xvYcc601 extended colorimetry");
					errorCode = FALSE;
				}
				else if (!colorimetryDataBlock_SupportsXvYcc709(&colorimetry)
						&& videoParams_GetExtColorimetry(video) == 1)
				{
					error_Set(ERR_SINK_DOES_NOT_SUPPORT_XVYCC709_COLORIMETRY);
					printk("Sink does NOT support xvYcc709 extended colorimetry");
					errorCode = FALSE;
				}
				else
				{
					error_Set(ERR_EXTENDED_COLORIMETRY_PARAMS_INVALID);
					printk("Invalid extended colorimetry parameters");
					errorCode = FALSE;
				}
			}
			else
			{
				error_Set(ERR_SINK_DOES_NOT_SUPPORT_EXTENDED_COLORIMETRY);
				errorCode = FALSE;
			}
		}
	}
	else
	{ /* DVI mode */
		if (videoParams_GetColorResolution(video) > 8)
		{
			error_Set(ERR_COLOR_DEPTH_NOT_SUPPORTED);
			printk("DVI - deep color not supported");
			errorCode = FALSE;
		}
		if (videoParams_GetEncodingOut(video) != RGB)
		{
			error_Set(ERR_DVI_MODE_WITH_YCC_ENCODING);
			printk("DVI mode does not support video encoding other than RGB");
			errorCode = FALSE;
		}
		if (videoParams_IsPixelRepetition(video))
		{
			error_Set(ERR_DVI_MODE_WITH_PIXEL_REPETITION);
			printk("DVI mode does not support pixel repetition");
			errorCode = FALSE;
		}
		if (videoParams_GetTmdsClock(video) > 16500)
		{
			printk("Sink must support DVI dual-link");
		}
		/* check colorimetry data */
		if ((videoParams_GetColorimetry(video) == EXTENDED_COLORIMETRY))
		{
			error_Set(ERR_DVI_MODE_WITH_EXTENDED_COLORIMETRY);
			printk("DVI does not support extended colorimetry");
			errorCode = FALSE;
		}
	}
	/*
	 * DTD check
	 * always checking VALID to minimise code execution (following probability)
	 * this video code is to be supported by all dtv's
	 */
	valid = (dtd_GetCode(videoParams_GetDtd(video)) == 1) ? TRUE : FALSE;
	if (!valid)
	{
		for (i = 0; i < api_EdidDtdCount(); i++)
		{
			api_EdidDtd(i, &dtd);
			if (dtd_GetCode(videoParams_GetDtd(video)) != (u8) (-1))
			{
				if (dtd_GetCode(videoParams_GetDtd(video)) == dtd_GetCode(&dtd))
				{
					valid = TRUE;
					break;
				}
			}
			else if (dtd_IsEqual(videoParams_GetDtd(video), &dtd))
			{
				valid = TRUE;
				break;
			}
		}
	}
	if (!valid)
	{
		if (dtd_GetCode(videoParams_GetDtd(video)) != (u8) (-1))
		{
			for (i = 0; i < api_EdidSvdCount(); i++)
			{
				api_EdidSvd(i, &svd);
				if ((unsigned) (dtd_GetCode(videoParams_GetDtd(video)))
						== shortVideoDesc_GetCode(&svd))
				{
					valid = TRUE;
					break;
				}
			}
		}
	}
	if (!valid)
	{
		error_Set(ERR_SINK_DOES_NOT_SUPPORT_SELECTED_DTD);
		printk("Sink does NOT indicate support for selected DTD");
		errorCode = FALSE;
	}
	/* check quantization range */
	if (api_EdidVideoCapabilityDataBlock(&capability) == TRUE)
	{
		if (!videoCapabilityDataBlock_GetQuantizationRangeSelectable(
				&capability) && videoParams_GetRgbQuantizationRange(video) > 1)
		{
			printk("Sink does NOT indicate support for selected quantization range");
		}
	}
	return errorCode;
}
Esempio n. 5
0
/**
 * Check audio parameters against read EDID structure to ensure
 * compatibility with sink.
 * @param audio audio parameters data structure
 */
static int api_CheckParamsAudio(audioParams_t * audio)
{
	unsigned i = 0;
	int bitSupport = -1;
	shortAudioDesc_t sad;
	speakerAllocationDataBlock_t allocation;
	u8 errorCode = TRUE;
	int valid = FALSE;
	/* array to translate from AudioInfoFrame code to EDID Speaker Allocation data block bits */
	const u8 sadb[] =
	{ 1, 3, 5, 7, 17, 19, 21, 23, 9, 11, 13, 15, 25, 27, 29, 31, 73, 75, 77,
			79, 33, 35, 37, 39, 49, 51, 53, 55, 41, 43, 45, 47 };

	LOG_TRACE();
	if (!api_EdidSupportsBasicAudio())
	{
		error_Set(ERR_SINK_DOES_NOT_SUPPORT_AUDIO);
		printk("Sink does NOT support audio");
		return FALSE;
	}
	/* check if audio type supported */
	for (i = 0; i < api_EdidSadCount(); i++)
	{
		api_EdidSad(i, &sad);
		if (audioParams_GetCodingType(audio) == shortAudioDesc_GetFormatCode(
				&sad))
		{
			bitSupport = i;
			break;
		}
	}
	if (bitSupport >= 0)
	{
		api_EdidSad(bitSupport, &sad);
		/* 192 kHz| 176.4 kHz| 96 kHz| 88.2 kHz| 48 kHz| 44.1 kHz| 32 kHz */
		switch (audioParams_GetSamplingFrequency(audio))
		{
		case 32000:
			valid = shortAudioDesc_Support32k(&sad);
			break;
		case 44100:
			valid = shortAudioDesc_Support44k1(&sad);
			break;
		case 48000:
			valid = shortAudioDesc_Support48k(&sad);
			break;
		case 88200:
			valid = shortAudioDesc_Support88k2(&sad);
			break;
		case 96000:
			valid = shortAudioDesc_Support96k(&sad);
			break;
		case 176400:
			valid = shortAudioDesc_Support176k4(&sad);
			break;
		case 192000:
			valid = shortAudioDesc_Support192k(&sad);
			break;
		default:
			valid = FALSE;
			break;
		}
		if (!valid)
		{
			error_Set(ERR_SINK_DOES_NOT_SUPPORT_AUDIO_SAMPLING_FREQ);
			LOG_WARNING2("Sink does NOT support audio sampling frequency", audioParams_GetSamplingFrequency(audio));
			errorCode = FALSE;
		}
		if (audioParams_GetCodingType(audio) == PCM)
		{
			/* 24 bit| 20 bit| 16 bit */
			switch (audioParams_GetSampleSize(audio))
			{
			case 16:
				valid = shortAudioDesc_Support16bit(&sad);
				break;
			case 20:
				valid = shortAudioDesc_Support20bit(&sad);
				break;
			case 24:
				valid = shortAudioDesc_Support24bit(&sad);
				break;
			default:
				valid = FALSE;
				break;
			}
			if (!valid)
			{
				error_Set(ERR_SINK_DOES_NOT_SUPPORT_AUDIO_SAMPLE_SIZE);
				LOG_WARNING2("Sink does NOT support audio sample size", audioParams_GetSampleSize(audio));
				errorCode = FALSE;
			}
		}
		/* check Speaker Allocation */
		if (api_EdidSpeakerAllocationDataBlock(&allocation) == TRUE)
		{
			LOG_DEBUG2("Audio channel allocation sent", sadb[audioParams_GetChannelAllocation(audio)]);
			LOG_DEBUG2("Audio channel allocation accepted", speakerAllocationDataBlock_GetSpeakerAllocationByte(&allocation));
			valid = (sadb[audioParams_GetChannelAllocation(audio)]
					& speakerAllocationDataBlock_GetSpeakerAllocationByte(
							&allocation))
					== sadb[audioParams_GetChannelAllocation(audio)];
			if (!valid)
			{
				error_Set(ERR_SINK_DOES_NOT_SUPPORT_ATTRIBUTED_CHANNELS);
				printk("Sink does NOT have attributed speakers");
				errorCode = FALSE;
			}
		}
	}
	else
	{
		error_Set(ERR_SINK_DOES_NOT_SUPPORT_AUDIO_TYPE);
		printk("Sink does NOT support audio type");
		errorCode = FALSE;
	}
	return errorCode;
}
Esempio n. 6
0
u8 edid_ParseDataBlock(u16 baseAddr, u8 * data)
{
	u8 tag = bitOperation_BitField(data[0], 5, 3);
	u8 length = bitOperation_BitField(data[0], 0, 5);
	u8 c = 0;
	shortAudioDesc_t tmpSad;
	shortVideoDesc_t tmpSvd;
	LOG_TRACE3("TAG", tag, length);
	switch (tag)
	{
	case 0x1: /* Audio Data Block */
		for (c = 1; c < (length + 1); c += 3)
		{
			shortAudioDesc_Parse(&tmpSad, data + c);
			if (edid_mSadIndex < (sizeof(edid_mSad) / sizeof(shortAudioDesc_t)))
			{
				edid_mSad[edid_mSadIndex++] = tmpSad;
			}
			else
			{
				error_Set(ERR_SHORT_AUDIO_DESC_BUFFER_FULL);
				LOG_WARNING("buffer full - SAD ignored");
			}
		}
		break;
	case 0x2: /* Video Data Block */
		for (c = 1; c < (length + 1); c++)
		{
			shortVideoDesc_Parse(&tmpSvd, data[c]);
			if (edid_mSvdIndex < (sizeof(edid_mSvd) / sizeof(shortVideoDesc_t)))
			{
				edid_mSvd[edid_mSvdIndex++] = tmpSvd;
			}
			else
			{
				error_Set(ERR_SHORT_VIDEO_DESC_BUFFER_FULL);
				LOG_WARNING("buffer full - SVD ignored");
			}
		}
		break;
	case 0x3: /* Vendor Specific Data Block */
	{
		u32 ieeeId = bitOperation_Bytes2Dword(0x00, data[3], data[2], data[1]);
		if (ieeeId == 0x000C03)
		{ /* HDMI */
			if (hdmivsdb_Parse(&edid_mHdmivsdb, data) != TRUE)
			{
				LOG_WARNING("HDMI Vendor Specific Data Block corrupt");
			}
		}
		else
		{
			LOG_WARNING2("Vendor Specific Data Block not parsed", ieeeId);
		}
		break;
	}
	case 0x4: /* Speaker Allocation Data Block */
		if (speakerAllocationDataBlock_Parse(&edid_mSpeakerAllocationDataBlock,
				data) != TRUE)
		{
			LOG_WARNING("Speaker Allocation Data Block corrupt");
		}
		break;
	case 0x7:
	{
		u8 extendedTag = data[1];
		switch (extendedTag)
		{
		case 0x00: /* Video Capability Data Block */
			if (videoCapabilityDataBlock_Parse(&edid_mVideoCapabilityDataBlock,
					data) != TRUE)
			{
				LOG_WARNING("Video Capability Data Block corrupt");
			}
			break;
		case 0x05: /* Colorimetry Data Block */
			if (colorimetryDataBlock_Parse(&edid_mColorimetryDataBlock, data)
					!= TRUE)
			{
				LOG_WARNING("Colorimetry Data Block corrupt");
			}
			break;
		case 0x04: /* HDMI Video Data Block */
		case 0x12: /* HDMI Audio Data Block */
			break;
		default:
			LOG_WARNING2("Extended Data Block not parsed", extendedTag);
			break;
		}
		break;
	}
	default:
		LOG_WARNING2("Data Block not parsed", tag);
		break;
	}
	return length + 1;
}
Esempio n. 7
0
int edid_ParseBlock(u16 baseAddr, u8 * buffer)
{
	const unsigned DTD_SIZE = 0x12;
	const unsigned TIMING_MODES = 0x36;
	dtd_t tmpDtd;
	unsigned c = 0;
	unsigned i = 0;
	LOG_TRACE();
	if (edid_mCurrBlockNo == 0)
	{
		if (buffer[0] == 0x00)
		{ /* parse block zero */
			edid_mBlocksNo = buffer[126] + 1;
			/* parse DTD's */
			for (i = TIMING_MODES; i < (TIMING_MODES + (DTD_SIZE * 4)); i
					+= DTD_SIZE)
			{
				if (bitOperation_Bytes2Word(buffer[i + 1], buffer[i + 0]) > 0)
				{
					if (dtd_Parse(&tmpDtd, buffer + i) == TRUE)
					{
						if (edid_mDtdIndex < (sizeof(edid_mDtd)
								/ sizeof(dtd_t)))
						{
							edid_mDtd[edid_mDtdIndex++] = tmpDtd;
						}
						else
						{
							error_Set(ERR_DTD_BUFFER_FULL);
							LOG_WARNING("buffer full - DTD ignored");
						}
					}
					else
					{
						LOG_WARNING("DTD corrupt");
					}
				}
				else if ((buffer[i + 2] == 0) && (buffer[i + 4] == 0))
				{
					/* it is a Display-monitor Descriptor */
					if (buffer[i + 3] == 0xFC)
					{ /* Monitor Name */
						for (c = 0; c < 13; c++)
						{
							edid_mMonitorName[c] = buffer[i + c + 5];
						}
					}
					else if (buffer[i + 3] == 0xFD)
					{ /* Monitor Range Limits */
						if (monitorRangeLimits_Parse(&edid_mMonitorRangeLimits,
								buffer + i) != TRUE)
						{
							LOG_WARNING2("Monitor Range Limits corrupt", i);
						}
					}
				}
			}
		}
	}
	else if (buffer[0] == 0xF0)
	{ /* Block Map Extension */
		/* last is checksum */
		for (i = 1; i < (sizeof(edid_mBuffer) - 1); i++)
		{
			if (buffer[i] == 0x00)
			{
				break;
			}
		}
		if (edid_mBlocksNo < 128)
		{
			if (i > edid_mBlocksNo)
			{ /* N (no of extensions) does NOT include Block maps */
				edid_mBlocksNo += 2;
			}
			else if (i == edid_mBlocksNo)
			{
				edid_mBlocksNo += 1;
			}
		}
		else
		{
			i += 127;
			if (i > edid_mBlocksNo)
			{ /* N (no of extensions) does NOT include Block maps */
				edid_mBlocksNo += 3;
			}
			else if (i == edid_mBlocksNo)
			{
				edid_mBlocksNo += 1;
			}
		}
	}
	else if (buffer[0] == 0x02)
	{ /* CEA Extension block */
		if (buffer[1] == 0x03)
		{ /* revision number (only rev3 is allowed by HDMI spec) */
			u8 offset = buffer[2];
			edid_mYcc422Support = bitOperation_BitField(buffer[3], 4, 1) == 1;
			edid_mYcc444Support = bitOperation_BitField(buffer[3], 5, 1) == 1;
			edid_mBasicAudioSupport = bitOperation_BitField(buffer[3], 6, 1)
					== 1;
			edid_mUnderscanSupport = bitOperation_BitField(buffer[3], 7, 1)
					== 1;
			if (offset != 4)
			{
				for (i = 4; i < offset; i += edid_ParseDataBlock(baseAddr,
						buffer + i))
					;
			}
			/* last is checksum */
			for (i = offset, c = 0; i < (sizeof(edid_mBuffer) - 1) && c < 6; i
					+= DTD_SIZE, c++)
			{
				if (dtd_Parse(&tmpDtd, buffer + i) == TRUE)
				{
					if (edid_mDtdIndex < (sizeof(edid_mDtd) / sizeof(dtd_t)))
					{
						edid_mDtd[edid_mDtdIndex++] = tmpDtd;
					}
					else
					{
						error_Set(ERR_DTD_BUFFER_FULL);
						LOG_WARNING("buffer full - DTD ignored");
					}
				}
			}
		}
	}
	return TRUE;
}
Esempio n. 8
0
void *max_jit_openni_new(t_symbol *s, long argc, t_atom *argv)
{
	t_max_jit_openni	*x;
	void				*o;
	long				i;
	
	x = (t_max_jit_openni*)max_jit_obex_new(max_jit_openni_class, gensym("jit_openni"));
	if (x)
	{
		o = jit_object_new(gensym("jit_openni"), x);	// instantiate jit.openni jitter object
		if (o)
		{
			// typically, max_jit_mop_setup_simple(x, o, argc, argv) is called here to handle standard MOP max wrapper setup tasks
			// however, I need to create a max only outlet between the MOP outlets and dumpout, so will use the code from MAx SDK 21.6.
			max_jit_obex_jitob_set(x,o);
			max_jit_obex_dumpout_set(x,outlet_new(x,NULL));
			x->osc_outlet = (t_object *)outlet_new(x, NULL);
			max_jit_mop_setup(x);
			max_jit_mop_inputs(x);
			max_jit_mop_outputs(x);
			x->chrSkeletonOutputFormat = 0;
			max_jit_mop_matrix_args(x,argc,argv);

			max_jit_attr_args(x, argc, argv); // process attribute arguments, like auto handling of @attribute's
#ifdef _DEBUG
			for (i = 0; i < argc; i++)
			{
				switch (atom_gettype(&(argv[i])))
				{
					case A_LONG:
						LOG_COMMENT3("arg %ld: long (%ld)", i, atom_getlong(&(argv[i])));
						break;
					case A_FLOAT:
						LOG_COMMENT3("arg %ld: float (%f)", i, atom_getfloat(&(argv[i])));
						break;
					case A_SYM:
						LOG_COMMENT3("arg %ld: symbol (%s)", i, atom_getsym(&(argv[i]))->s_name);
						break;
					default:
						LOG_WARNING2("arg %ld: forbidden argument", i); 
				}
			}
#endif
			if(RegisterJitOpenNIEventCallbacks((t_jit_openni *)max_jit_obex_jitob_get(x), max_jit_openni_post_events, &(x->pRegistrationForEvents)))
			{
				LOG_ERROR("jit.openni: could not register for jit.openni event callbacks");
				max_jit_openni_free(x);
				freeobject((t_object*)x);
				x = NULL;
			}
			else
			{
				LOG_DEBUG2("jit.openni: successfully registered for jit.openni event callbacks w/ regID=%x", x->pRegistrationForEvents);
			}
		}
		else
		{
			LOG_ERROR("jit.openni: could not allocate object");
			max_jit_obex_free(x);
			freeobject((t_object*)x);
			x = NULL;
		}
	}
	return(x);
}