API Application Example

#include	<stdio.h>		/* printf */
#include	<stdint.h>		/* uint??_t */
#include	<string.h>		/* for memset */
#include	<unistd.h>		/* for open/close .. */
#include	<fcntl.h>		/* for O_RDWR */
#include	<sys/ioctl.h>	/* for ioctl */
#include	<sys/mman.h>	/* for mmap */
#include	<linux/fb.h>	/* for fb_var_screeninfo, FBIOGET_VSCREENINFO */
#include	<linux/input.h>
#include	<poll.h>
#include	<sys/fcntl.h>	/* for O_RDWR */

#include	"directfb/directfb.h"	/* 항상 UI.h 와 함께 UI.h 보다 먼저 */
#include	"UI.h"					/* direct fb */

#include	"MMD1100.h"		/* MSR */
#include	"Buzzer.h"
#include	"LED.h"
#include	"KeyBackLight.h"
#include	"ThermalPrinter.h"

#include	<termios.h>			/* struct termios */


/*
DirectFB support still image type
	jpg
	png
	gif

*/

/*	Application Action
Key			: Test Action
-------------------------------------------------------------------------------------
F1			: Display VI_logo_320_240_R90.jpg
F2			: Display VI_logo_320_240_R270.jpg
F3			: Draw Blue Box
F4			: Clear Screen
F5			: Display String..
F6 (*)		: LCD Back light -, Read Thermal Printer Info
F7 (#)		: LCD Back light +
F8 (Up)		: Key Backlight On
F9 (Down)	: Key Backlight Off
F10 (Scan)	: -
ESC			: - Printer Pattern
BACKSPACE	: - Throw Printer paper
ENTER		: Exit App
1			: LED On  - DEVICE_LED_B14 = HANDY_READY    or PRINTER_BUSY     or AP_STATUS
			: Beep 도
2			: LED Off - DEVICE_LED_B14 = HANDY_READY    or PRINTER_BUSY     or AP_STATUS
			: Beep 레
3			: LED On  - DEVICE_LED_A25 = HANDY_PROCESS  or PRINTER_READY
			: Beep 미
4			: LED Off - DEVICE_LED_A25 = HANDY_PROCESS  or PRINTER_READY
			: Beep 파
5			: LED On  - DEVICE_LED_C21 = HANDY_COLPLETE or 
			: Beep 솔
6			: LED Off - DEVICE_LED_C21 = HANDY_COLPLETE or 
			: Beep 라
7			: LED On  - DEVICE_LED_B15 = HANDY_ERROR    or PRINTER_NO_PAPER or AP_ERROR
			: Beep 시
8			: LED Off - DEVICE_LED_B15 = HANDY_ERROR    or PRINTER_NO_PAPER or AP_ERROR
			: Beep 옥타브 내림
9			: Beep 옥타브 올림
0			: Read MMD1100 version
*/

//#define	TEST_LTE_MODEM

//#define	TEST_THERMAL_PRINTER

/***************************************************************************/
/*	For directfb
*/
/***************************************************************************/
#ifdef	TEST_LTE_MODEM
#define	LTE_INITIAL_IMAGE_FILE		"320x480.jpg"
#endif	/* TEST_LTE_MODEM */

#define	TEST_IMAGE_FILE_1			"VI_logo_320_240_R90.jpg"
#define	TEST_IMAGE_FILE_2			"VI_logo_320_240_R270.jpg"

#define	TEST_DISPLAY_STRING			"밸류이노베이션 VI"

/***************************************************************************/
/*	For Test LCD BackLight
*/
/***************************************************************************/
#define	DEVICE_LCD_BACKLIGHT	"/sys/class/backlight/backlight/brightness"


#ifdef	TEST_LTE_MODEM

#define	DEVICE_LTE_TEST_LED_SW		"/sys/class/leds/lte_sw/brightness"
#define	DEVICE_LTE_TEST_LED_KEY		"/sys/class/leds/lte_key/brightness"
//#define	DEVICE_LTE_TEST_LED_AP		"/sys/class/leds/lte_ap_ready/brightness"
//#define	DEVICE_LTE_TEST_LED_USB_ON	"/sys/class/leds/lte_usb_on/brightness"
//#define	DEVICE_LTE_TEST_LED_DTR		"/sys/class/leds/lte_dtr/brightness"

int	lte_on_off_switch(bool Switch/*true=on, false=Off*/)
{
	FILE *	pDeviceFile;
	char	pString[2] = { 0, 0 };
	int		StringLength;

	pDeviceFile = fopen ( DEVICE_LTE_TEST_LED_SW, "w+");
	if ( pDeviceFile == (FILE *)0 )
	{
		return	-2;
	}

	if ( Switch == true )
	{
		pString[0] = '1';
	}
	else
	{
		pString[0] = '0';
	}
	StringLength = (int)strlen(pString);
	if ( fwrite ( pString, StringLength, 1, pDeviceFile ) < 0 )
	{
		return	-3;
	}

	fclose ( pDeviceFile );

	return	0;
}

int	lte_power_key(bool Pressed/*true=on, false=Off*/)
{
	FILE *	pDeviceFile;
	char	pString[2] = { 0, 0 };
	int		StringLength;

	pDeviceFile = fopen ( DEVICE_LTE_TEST_LED_KEY, "w+");
	if ( pDeviceFile == (FILE *)0 )
	{
		return	-2;
	}

	if ( Pressed == true )
	{
		pString[0] = '1';
	}
	else
	{
		pString[0] = '0';
	}
	StringLength = (int)strlen(pString);
	if ( fwrite ( pString, StringLength, 1, pDeviceFile ) < 0 )
	{
		return	-3;
	}

	fclose ( pDeviceFile );

	return	0;
}

#if	0

#define	DEVICE_LTE								"/dev/ttyS4"
#define	DEVICE_LTE_DEFAULT_BAUDRATE				115200

struct termios BackupTerminalInfo;

int	lte_open(int *pDeviceFileDescriptor)
{
	struct termios TerminalInfo;

	if ( pDeviceFileDescriptor == (int *)0 )
	{
		return	-2;
	}

	/* 화일을 연다. */
	*pDeviceFileDescriptor = open( DEVICE_LTE, (O_RDWR | O_NOCTTY) );
	if ( *pDeviceFileDescriptor < 0 )
	{
		*pDeviceFileDescriptor = -1;
		return	-1;
	}
	/* 현재 설정을 BackupTerminalInfo에 저장 */
	tcgetattr( *pDeviceFileDescriptor, &BackupTerminalInfo );
	memset( &TerminalInfo, 0, sizeof(TerminalInfo) );
	switch( DEVICE_LTE_DEFAULT_BAUDRATE )
	{
	case	19200:
		TerminalInfo.c_cflag = B19200 | CS8 | CSTOPB | CLOCAL | CREAD ; 
		break;
	case	38400:
		TerminalInfo.c_cflag = B38400 | CS8 | CSTOPB | CLOCAL | CREAD ; 
		break;
	case	57600:
		TerminalInfo.c_cflag = B57600 | CS8 | CSTOPB | CLOCAL | CREAD ; 
		break;
	case	115200:
		TerminalInfo.c_cflag = B115200 | CS8 | CSTOPB | CLOCAL | CREAD ; 
		break;
	case	9600:
	default:
		TerminalInfo.c_cflag = B9600 | CS8 | CSTOPB | CLOCAL | CREAD ; 
		break;
	}
	TerminalInfo.c_iflag = 0; /* IGNPAR? */
	TerminalInfo.c_oflag = 0;
	//set input mode (non-canonical, no echo,.....)
	TerminalInfo.c_lflag = 0;
	TerminalInfo.c_cc[VTIME] = 100;	/* time-out 값으로 사용된다. time-out 값은 TIME*0.1초 이다. */
	TerminalInfo.c_cc[VMIN]  = 0;	/* MIN은 read가 리턴되기 위한 최소한의 문자 개수 */

	tcflush( *pDeviceFileDescriptor, TCIFLUSH );
	tcsetattr( *pDeviceFileDescriptor, TCSANOW, &TerminalInfo );
	//	raw mode
	fcntl( *pDeviceFileDescriptor, F_SETFL, O_NONBLOCK );

	return	0;
}

int	lte_close(int DeviceFileDescriptor)
{

	if ( DeviceFileDescriptor < 0 )
	{
		return	-1;
	}

	/* 이전 상태로 되돌린다. */
	tcsetattr( DeviceFileDescriptor, TCSANOW, &BackupTerminalInfo );

	close( DeviceFileDescriptor );

	return	0;
}

int	lte_serial_polling(int DeviceFileDescriptor)
{
	struct	pollfd	PollFileDescriptor;
	uint32_t		Temp;
	int				Result;
	uint8_t			ReceivedByte;

	memset( &PollFileDescriptor, 0, sizeof(struct pollfd) );
	PollFileDescriptor.fd = DeviceFileDescriptor;
	PollFileDescriptor.events = POLLIN;
	PollFileDescriptor.revents = 0;

	Result = poll( (struct pollfd *)&PollFileDescriptor, 1, 300);	//	300 msec

	if ( (Result == 1) && ((PollFileDescriptor.revents & POLLIN) != 0) )
	{
		if ( read( DeviceFileDescriptor, &ReceivedByte, 1 ) == 1 )
		{
			printf( "Input %c\n", ReceivedByte );
		}
	}
	return	0;
}

#endif

#endif	/* TEST_LTE_MODEM */


/***************************************************************************/
/*	For Test LCD BackLight
*/
/***************************************************************************/
int	bright_set(const uint8_t Brightness)
{
	FILE *	pDeviceFile;
	char	pString[10] = {0};
	int		StringLength;

	pDeviceFile = fopen(DEVICE_LCD_BACKLIGHT, "w+");
	if ( pDeviceFile == (FILE *)0 )
	{
		printf("failed to open back light device : %s\n", DEVICE_LCD_BACKLIGHT);
		return	-1;
	}

	sprintf(pString, "%d", Brightness);
	StringLength = (int)strlen(pString);

	if ( fwrite(pString, StringLength, 1, pDeviceFile) < 0 )
	{
		return	-1;
	}

	fclose(pDeviceFile);

	return	0;
}

int bright_get(uint8_t *pBrightness)
{
	FILE *	pDeviceFile;
	char	pCommand[128] = {0};
	char	pString[10] = {0};

	char buf[10] = {0};
	int level = 0;

	if ( pBrightness == (uint8_t *)0 )
	{
		printf("bright_get : Input Parameter error\n");
		return	-1;
	}

	sprintf(pCommand, "cat %s", DEVICE_LCD_BACKLIGHT);
	pDeviceFile = popen(pCommand, "r");
	if ( pDeviceFile == (FILE *)0 )
	{
		return	-1;
	}

	while( fgets(pString, 10, pDeviceFile) );
	*pBrightness = (uint8_t)strtoul(pString, NULL, 10);

	fclose(pDeviceFile);

	return	0;
}

void	print_hex_dump(uint8_t *pBuffer, uint32_t ByteLengthForDump)
{
	uint32_t	Address;

	printf( "--------------------------------------------------------------------------------------------\n" );
	printf( "Address    | 0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09 0x0A 0x0B 0x0C 0x0D 0x0E 0x0F\n" );
	printf( "--------------------------------------------------------------------------------------------" );
for( Address = 0; Address < ByteLengthForDump; Address++ )
{
	if (( Address & 0x0000000F ) == 0 )
	{
		printf( "\n0x%08X :", Address );
	}
	printf ( " 0x%02X", pBuffer[Address] );
}
	printf( "\n--------------------------------------------------------------------------------------------\n" );
}

static	char	*pFontList[8] =
{
	"D2Coding.ttf",
	"NanumSquareR.ttf",
	"NanumGothic.ttf",
	"NanumGothicCoding.ttf",
	"NanumMyeongjo.ttf",
	"NanumBarunGothic.ttf",
	"NanumBrush.ttf",
	"NanumPen.ttf"
};


int	main()
{
	void *					pUI;

	uint32_t				KeyCode;
	bool					IsReleased;

#ifdef	TEST_THERMAL_PRINTER
	int						ThermalPrinter;
	uint32_t				ThermalPrinterDotsInLine;
	int						ThermalPrinterImageSize;
	char					pThermapPrinterTestString[100];
#endif	/* TEST_THERMAL_PRINTER */

	int						IsInLoop;
	uint32_t				Octave;
	uint8_t					Brightness;

	int						DeviceFileDescriptorForMSR;
	MSRTrack_t				MSRTrack;
	MMD1100Response_t		MSRResponse;
	uint32_t				IsNotTrack;
	uint8_t					pVersion[1024];
	int						ReadByteLength;
	uint8_t					pImageBuffer[10000];

#ifdef	TEST_LTE_MODEM
	int						DeviceLTE;
#endif	/* TEST_LTE_MODEM */

#ifdef	TEST_THERMAL_PRINTER
	thermal_printer_open( &ThermalPrinter );
#endif	/* TEST_THERMAL_PRINTER */

	if ( ui_initialize( &pUI, 0 ) != 0 )
	{
		printf( "ui_initialize() Fail!\n");
		return	-1;
	}

#ifdef	TEST_THERMAL_PRINTER
	if ( thermal_printer_get_dots_in_line( ThermalPrinter, &ThermalPrinterDotsInLine ) < 0 )
	{
		printf( "Fail to get Termal Printer Dots In Line\n" );
		ui_release( pUI );
		return	-1;
	}
	printf( "Termal Printer Dots In Line = %d\n", ThermalPrinterDotsInLine );

	if ( ui_printer_create_surface( pUI, ThermalPrinterDotsInLine/*SurfaceWidth*/, ThermalPrinterDotsInLine/*SurfaceHeight*/) < 0 )
	{
		printf( "Fail to ui_printer_create_surface()\n" );
		ui_release( pUI );
		return	-1;
	}
#endif	/* TEST_THERMAL_PRINTER */

	if ( ui_clear_screen( pUI ) != 0 )
	{
		printf( "ui_clear_screen() Fail!\n");
		ui_release( pUI );
		return	-1;
	}
	printf( "FillRectangle to clear surface OK!\n");

	if ( bright_get(&Brightness) != 0 )
	{
		printf("Fail to bright_get()\n");
	}
	else
	{
		printf("Brightness == %d\n", Brightness);
	}
	Brightness = 8;	/* */
	if( bright_set(Brightness) != 0 )
	{
		printf("Fail to bright_set(0)\n");
	}

	if ( buzzer_open() < 0 )
	{
		printf("Fail to buzzer_open\n");
	}

	if ( mmd1100_open( &DeviceFileDescriptorForMSR ) != 0 )
	{
		printf( "Fail to mmd1100_open\n" );
	}
	else
	{
		printf( "OK to mmd1100_open\n" );
	}

#ifdef	TEST_LTE_MODEM
	ui_draw_image( pUI, LTE_INITIAL_IMAGE_FILE, 0, 0 );
#endif	/* TEST_LTE_MODEM */

#ifdef	TEST_LTE_MODEM
	usleep( 100000 );	/* 100ms */
	lte_on_off_switch( true/*true=on, false=Off*/ );
	usleep( 50000 );	/* >=30ms */
	lte_power_key( true/*true=on, false=Off*/ );
	usleep( 200000 );	/* >=100ms */
	lte_power_key( false/*true=on, false=Off*/ );
#endif	/* TEST_LTE_MODEM */

#if	0
	if ( lte_open( &DeviceLTE ) != 0 )
	{
		printf( "Fail to ttyS4\n" );
	}
	else
	{
		printf( "OK to ttyS4\n" );
	}
//int	lte_close(int DeviceFileDescriptor)
	for ( KeyCode = 0; KeyCode < 10; KeyCode++ )
	{
		int waitcounter;
		if ( write( DeviceLTE, "AT+GMI", 6 ) != 0 )
		{
			printf( "Fail to w ttyS4\n" );
		}
		else
		{
			printf( "OK to W ttyS4\n" );
		}
		for ( waitcounter = 0; waitcounter < 10; waitcounter++ )
		{
			lte_serial_polling( DeviceLTE );
		}
		usleep( 1000000 );	/* 1 s */
	}

#endif	/* TEST_LTE_MODEM */

	Octave = 4;
	IsInLoop = 1;
	/* Start event loop */  
	while ( IsInLoop )
	{
		if ( ui_key_is_inputed( pUI, 100/*100ms MiliSecondWaitTimeout*/) == 0 )
		{
			uint8_t	ReceivedByte;

#if	1
			if ( mmd1100_receive( &MSRTrack, &MSRResponse, &IsNotTrack, 10000/*10ms ResponseTimeout*/) == 0 )
			{
				printf("MSR IN\n");
				if ( IsNotTrack == 1 )
				{
					switch ( MSRResponse.Command )
					{
					case	MMD1100_COMMAND_GET_VERSION:
						if ( MSRResponse.ErrorCode == 0 )
						{
							printf("   MMD1100_COMMAND_GET_VERSION : %s\n", MSRResponse.pData );
						}
						else
						{
							printf("   MMD1100_COMMAND_GET_VERSION : Error = 0x%02X\n", MSRResponse.ErrorCode );
						}
						break;
					case	MMD1100_COMMAND_LOAD_USER_PARAMETERS:
						break;
					case	MMD1100_COMMAND_UART_CALIBRATION:
						break;
					case	MMD1100_COMMAND_OTP_WRITE:
						break;
					case	MMD1100_COMMAND_GET_STATUS:
						break;
					case	MMD1100_COMMAND_READ_DATA_RETRY:
						break;
					case	MMD1100_COMMAND_SOFTWARE_RESET:
						break;
					default:
						break;
					}
				}
				else
				{
					int	i;
					if ( MSRTrack.ErrorCodeForTrack1 == 0 )
					{
						printf( "   Track 1 : " );
						for ( i = 0; i < MSRTrack.LengthOfTrack1; i++ )
						{
							printf( "%c", MSRTrack.pTrack1[i] );
						}
						printf( "\n" );
						if ( ( (MSRTrack.LengthOfTrack1 * 8) % 7 ) == 0 )
						{
							printf( " Length OK \n" );
						}
					}
					else
					{
						printf("   Track 1 : ErrorCode = 0x%02X\n", MSRTrack.ErrorCodeForTrack1 );
					}
					if ( MSRTrack.ErrorCodeForTrack2 == 0 )
					{
						printf( "   Track 2 Raw Data : (Length = %d)\n    ", MSRTrack.LengthOfRaw2 );
						for ( i = 0; i < MSRTrack.LengthOfRaw2; i++ )
						{
							printf( "%02X ", MSRTrack.pRaw2[i] );
						}
						printf( "\n" );
						printf( "   Track 2 : (Length = %d)\n    ", MSRTrack.LengthOfTrack2 );
						for ( i = 0; i < MSRTrack.LengthOfTrack2; i++ )
						{
							printf( "%c", MSRTrack.pTrack2[i] );
						}
						printf( "\n" );
					}
					else
					{
						printf("   Track 2 : ErrorCode = 0x%02X\n", MSRTrack.ErrorCodeForTrack2 );
					}
					if ( MSRTrack.ErrorCodeForTrack3 == 0 )
					{
						printf( "   Track 3 Raw Data : (Length = %d)\n    ", MSRTrack.LengthOfRaw3 );
						for ( i = 0; i < MSRTrack.LengthOfRaw3; i++ )
						{
							printf( "%02X ", MSRTrack.pRaw3[i] );
						}
						printf( "\n" );
						printf( "   Track 3 : (Length = %d)\n    ", MSRTrack.LengthOfTrack3 );
						for ( i = 0; i < MSRTrack.LengthOfTrack3; i++ )
						{
							printf( "%c", MSRTrack.pTrack3[i] );
						}
						printf( "\n" );
					}
					else
					{
						printf("   Track 3 : ErrorCode = 0x%02X\n", MSRTrack.ErrorCodeForTrack3 );
					}
				}
			}
#endif

			continue;
		}

		while ( ui_key_get_code( pUI, &KeyCode, &IsReleased ) == 0 )
		{
			switch ( KeyCode )
			{
			case	KEY_ESC:	/*Repeated input 3 times... TODO:check!!!*/
				printf("Key Code : KEY_ESC (0x%X)\n", KeyCode);
				if ( IsReleased == true )
				{	/* Key Released */
					;
				}
				else
				{
					;
				}
				break;
			case	KEY_1:
				printf("Key code : KEY_1 (0x%X)\n", KeyCode);
				if ( IsReleased == true )
				{	/* Key Released */
					led_switch(DEVICE_LED_B14, true/*On*/ );
					buzzer_off();
				}
				else
				{
					buzzer_on_code( MUSIC_FREQUENCY_CODE_C, Octave );	/* C(도)  */
				}
				break;
			case	KEY_2:
				printf("Key code : KEY_2 (0x%X)\n", KeyCode);
				if ( IsReleased == true )
				{	/* Key Released */
					led_switch(DEVICE_LED_B14, false/*Off*/ );
					buzzer_off();
				}
				else
				{
					buzzer_on_code( MUSIC_FREQUENCY_CODE_D, Octave );	/* D(레)  */
				}
				break;
			case	KEY_3:
				printf("Key code : KEY_3 (0x%X)\n", KeyCode);
				if ( IsReleased == true )
				{	/* Key Released */
					led_switch(DEVICE_LED_A25, true/*On*/ );
					buzzer_off();
				}
				else
				{
					buzzer_on_code( MUSIC_FREQUENCY_CODE_E, Octave );	/* E(미)  */
				}
				break;
			case	KEY_4:
				printf("Key code : KEY_4 (0x%X)\n", KeyCode);
				if ( IsReleased == true )
				{	/* Key Released */
					led_switch(DEVICE_LED_A25, false/*Off*/ );
					buzzer_off();
				}
				else
				{
					buzzer_on_code( MUSIC_FREQUENCY_CODE_F, Octave );	/* F(파)  */
				}
				break;
			case	KEY_5:
				printf("Key code : KEY_5 (0x%X)\n", KeyCode);
				if ( IsReleased == true )
				{	/* Key Released */
					led_switch(DEVICE_LED_C21, true/*On*/ );
					buzzer_off();
				}
				else
				{
					buzzer_on_code( MUSIC_FREQUENCY_CODE_G, Octave );	/* G(솔)  */
				}
				break;
			case	KEY_6:
				printf("Key code : KEY_6 (0x%X)\n", KeyCode);
				if ( IsReleased == true )
				{	/* Key Released */
					led_switch(DEVICE_LED_C21, false/*Off*/ );
					buzzer_off();
				}
				else
				{
					buzzer_on_code( MUSIC_FREQUENCY_CODE_A, Octave );	/* A(라)  */
				}
				break;
			case	KEY_7:
				printf("Key code : KEY_7 (0x%X)\n", KeyCode);
				if ( IsReleased == true )
				{	/* Key Released */
					led_switch(DEVICE_LED_B15, true/*On*/ );
					buzzer_off();
				}
				else
				{
					buzzer_on_code( MUSIC_FREQUENCY_CODE_B, Octave );	/* B(시)  */
				}
				break;
			case	KEY_8:
				printf("Key code : KEY_8 (0x%X)\n", KeyCode);
				if ( IsReleased == true )
				{	/* Key Released */
					led_switch(DEVICE_LED_B15, false/*Off*/ );
					buzzer_off();
				}
				else
				{
					buzzer_on_code( MUSIC_FREQUENCY_CODE_C, (Octave + 1) );	/* C(도)  */
				}
				break;
			case	KEY_9:
				printf("Key code : KEY_9 (0x%X)\n", KeyCode);
				if ( IsReleased == true )
				{	/* Key Released */
#ifdef	TEST_THERMAL_PRINTER
					uint32_t	Uint32Value;
					bool		BoolValue;

					if ( thermal_printer_get_dots_in_line( ThermalPrinter, &Uint32Value ) < 0 )
					{
						printf( " Thermal Printer : Dots In Line Get Fail\n" );
					}
					else
					{
						printf( " Thermal Printer : Dots In Line = %d\n", Uint32Value );
					}
					if ( thermal_printer_get_heater_temperature( ThermalPrinter, &Uint32Value ) < 0 )
					{
						printf( " Thermal Printer : Heater Temperature Get Fail\n" );
					}
					else
					{
						printf( " Thermal Printer : Heater Temperature = %d\n", Uint32Value );
					}
					if ( thermal_printer_get_heater_adc_raw_value( ThermalPrinter, &Uint32Value ) < 0 )
					{
						printf( " Thermal Printer : Heater Temperature ADC raw data Get Fail\n" );
					}
					else
					{
						printf( " Thermal Printer : Heater Temperature ADC raw data = %d\n", Uint32Value );
					}
					if ( thermal_printer_get_heater_power_state( ThermalPrinter, &BoolValue ) < 0 )
					{
						printf( " Thermal Printer : Heater Power State Get Fail\n" );
					}
					else
					{
						if ( BoolValue == true )
						{
							printf( " Thermal Printer : Heater Power State true\n" );
						}
						else
						{
							printf( " Thermal Printer : Heater Power State false\n" );
						}
					}
					if ( thermal_printer_get_heater_overheat_state( ThermalPrinter, &BoolValue ) < 0 )
					{
						printf( " Thermal Printer : Heater overheat State Get Fail\n" );
					}
					else
					{
						if ( BoolValue == true )
						{
							printf( " Thermal Printer : Heater overheat State true\n" );
						}
						else
						{
							printf( " Thermal Printer : Heater overheat State false\n" );
						}
					}
					if ( thermal_printer_get_paper_state( ThermalPrinter, &BoolValue ) < 0 )
					{
						printf( " Thermal Printer : paper State Get Fail\n" );
					}
					else
					{
						if ( BoolValue == true )
						{
							printf( " Thermal Printer : paper State true\n" );
						}
						else
						{
							printf( " Thermal Printer : paper State false\n" );
						}
					}
					if ( thermal_printer_get_cover_state( ThermalPrinter, &BoolValue ) < 0 )
					{
						printf( " Thermal Printer : cover State Get Fail\n" );
					}
					else
					{
						if ( BoolValue == true )
						{
							printf( " Thermal Printer : cover State true\n" );
						}
						else
						{
							printf( " Thermal Printer : cover State false\n" );
						}
					}
#endif	/* TEST_THERMAL_PRINTER */
				}
				else
				{
					;
				}
				break;
			case	KEY_0:
				if ( IsReleased == true )
				{	/* Key Released */
					uint32_t	MakedPacketByteLength;

					if ( mmd1100_make_packet(pVersion,
											&MakedPacketByteLength,
											MMD1100_COMMAND_GET_VERSION,
											(uint8_t *)0 ) != 0 )
					{
						printf( "Fail to mmd1100_make_packet\n" );
					}
					else
					{
						if ( mmd1100_send(pVersion, MakedPacketByteLength) > 0 )
						{
							printf( "OK to mmd1100_send\n" );
						}
						else
						{
							printf( "Fail to mmd1100_send\n" );
						}
					}
				}
				printf("Key code : KEY_0 (0x%X)\n", KeyCode);
				break;
			case	KEY_BACKSPACE:
				if ( IsReleased == true )
				{	/* Key Released */
#ifdef	TEST_THERMAL_PRINTER
					thermal_printer_paper_throw( ThermalPrinter, 120/*Line*/ );
					printf( "thermal_printer_paper_throw 120 lines\n" );
#endif	/* TEST_THERMAL_PRINTER */
				}
				printf("Key code : KEY_BACKSPACE (0x%X)\n", KeyCode);
				break;
			case	KEY_ENTER:
				printf("Key code : KEY_ENTER (0x%X)\n", KeyCode);
				if ( IsReleased == true )
				{	/* Key Released */
#ifdef	TEST_THERMAL_PRINTER
					thermal_printer_print_test_pattern( ThermalPrinter, DEVICE_THERMAL_PRINTER_TEST_PATTERN_1 );
usleep(100000);
					thermal_printer_paper_throw( ThermalPrinter, 100/*Line*/ );
usleep(100000);
					thermal_printer_print_test_pattern( ThermalPrinter, DEVICE_THERMAL_PRINTER_TEST_PATTERN_2 );
usleep(100000);
					thermal_printer_paper_throw( ThermalPrinter, 100/*Line*/ );
usleep(100000);
					thermal_printer_print_test_pattern( ThermalPrinter, DEVICE_THERMAL_PRINTER_TEST_PATTERN_3 );
usleep(100000);
					thermal_printer_paper_throw( ThermalPrinter, 100/*Line*/ );
usleep(100000);
					thermal_printer_print_test_pattern( ThermalPrinter, DEVICE_THERMAL_PRINTER_TEST_PATTERN_4 );
usleep(100000);
					thermal_printer_paper_throw( ThermalPrinter, 150/*Line*/ );
#else	/* TEST_THERMAL_PRINTER */
					IsInLoop = 0;	/* Exit */
#endif	/* TEST_THERMAL_PRINTER */
				}
				break;
			case	KEY_F1:
				printf("Key code : KEY_F1 (0x%X)\n", KeyCode);
				if ( IsReleased == true )
				{
					ui_draw_image( pUI, TEST_IMAGE_FILE_1, 0, 0 );
				}
				break;
			case	KEY_F2:
				printf("Key code : KEY_F2 (0x%X)\n", KeyCode);
				if ( IsReleased == true )
				{
					ui_draw_image( pUI, TEST_IMAGE_FILE_2, 0, 0 );
				}
				break;
			case	KEY_F3:
				printf("Key code : KEY_F3 (0x%X)\n", KeyCode);
				if ( IsReleased == true )
				{	/* Key Released */
					UIcolor_t Color;
					Color.B = 0xFF;
					Color.G = 0x00;
					Color.R = 0xFF;
					Color.Alpha = 0xFF;
					ui_fill_rectangle( pUI, Color, 100, 100, 40, 80 );
				}
				break;
			case	KEY_F4:
				printf("Key code : KEY_F4 (0x%X)\n", KeyCode);
				if ( IsReleased == true )
				{	/* Key Released */
					ui_clear_screen( pUI );
				}
				break;
			case	KEY_F5:
				printf("Key code : KEY_F5 (0x%X)\n", KeyCode);
				if ( IsReleased == true )
				{
					UIcolor_t Color;
					Color.B = 0xFF;
					Color.G = 0x00;
					Color.R = 0xFF;
					Color.Alpha = 0xFF;
#ifdef	TEST_THERMAL_PRINTER
					ui_draw_string( pUI, Color, 20, 40, 280, 400, TEST_DISPLAY_STRING, UI_TEXT_LAYOUT_TOP_LEFT );
					ui_draw_string( pUI, Color, 20, 40, 280, 400, TEST_DISPLAY_STRING, UI_TEXT_LAYOUT_MIDDLE_CENTER );
					ui_draw_string( pUI, Color, 20, 40, 280, 400, TEST_DISPLAY_STRING, UI_TEXT_LAYOUT_BOTTOM_RIGHT );
					ui_draw_rectangle( pUI, Color, 20, 40, 280, 400 );
#else	/* TEST_THERMAL_PRINTER */
					ui_draw_string( pUI, Color, 20, 40, 200, 240, TEST_DISPLAY_STRING, UI_TEXT_LAYOUT_TOP_LEFT );
					ui_change_font( pUI, "NanumBrush.ttf", 28);
					ui_draw_string( pUI, Color, 20, 40, 200, 240, TEST_DISPLAY_STRING, UI_TEXT_LAYOUT_MIDDLE_CENTER );
					ui_change_font( pUI, "NanumPen.ttf", 28);
					ui_draw_string( pUI, Color, 20, 40, 200, 240, TEST_DISPLAY_STRING, UI_TEXT_LAYOUT_BOTTOM_RIGHT );

					ui_change_font( pUI, "NanumGothic.ttf", 22);
					ui_draw_string( pUI, Color, 20, 80, 200, 160, TEST_DISPLAY_STRING, UI_TEXT_LAYOUT_TOP_LEFT );
					ui_change_font( pUI,"NanumMyeongjo.ttf", 22);
					ui_draw_string( pUI, Color, 20, 80, 200, 160, TEST_DISPLAY_STRING, UI_TEXT_LAYOUT_BOTTOM_RIGHT );

					ui_change_font( pUI, "D2Coding.ttf", 22);
					ui_draw_rectangle( pUI, Color, 20, 40, 200, 240 );
#endif	/* TEST_THERMAL_PRINTER */
				}
				break;
			case	KEY_F6:	/* '*' or '00' */
				if ( IsReleased == true )
				{	/* Key Released */
#ifdef	TEST_THERMAL_PRINTER
					ReadByteLength = thermal_printer_read(ThermalPrinter, pVersion, 100);
					printf( "ThermalPrinter read [%d : %s]\n", ReadByteLength, pVersion );
#else	/* TEST_THERMAL_PRINTER */
					if( Brightness != 8 )
					{
						Brightness ++;
						if( bright_set(Brightness) != 0 )
						{
							printf("Fail to bright_set\n");
						}
						printf("bright -\n");
					}
#endif	/* TEST_THERMAL_PRINTER */
				}
				printf("Key code : KEY_F6 (0x%X)\n", KeyCode);
				break;
			case	KEY_F7:	/* '#' or '000' */
				if ( IsReleased == true )
				{	/* Key Released */
#ifdef	TEST_THERMAL_PRINTER
					uint32_t	LineHeight;
					uint32_t	PrinterFontSize;
					uint32_t	FontFileIndex;

					for ( FontFileIndex = 0; FontFileIndex < 8; FontFileIndex++ )
					{
						for ( PrinterFontSize = 16; PrinterFontSize <= 32; PrinterFontSize += 2 )
						{
							memset( pThermapPrinterTestString, 0, 100 );
							sprintf ( pThermapPrinterTestString, "%s %d", TEST_DISPLAY_STRING, PrinterFontSize );
							printf( "Thermal Printer Test String = %s\n", pThermapPrinterTestString );

							thermal_printer_get_dots_in_line( ThermalPrinter, &ThermalPrinterDotsInLine );
							printf( "Termal Printer Dots In Line = %d\n", ThermalPrinterDotsInLine );

/*							ui_printer_font_set( pUI, "D2Coding.ttf", PrinterFontSize );*/
							ui_printer_font_set( pUI, pFontList[FontFileIndex], PrinterFontSize );

							if ( ui_printer_font_get_line_height( pUI, &LineHeight ) < 0 )
							{
								printf( "Fail to Get Termal Printer Line Height\n" );
							}
							else
							{
								printf( "Termal Printer Line Height = %d\n", LineHeight );

								memset( pImageBuffer, 0, ((LineHeight * ThermalPrinterDotsInLine) / 8 ) );
								ThermalPrinterImageSize = ui_printer_string( pUI,
																			pFontList[FontFileIndex],
																			UI_TEXT_LAYOUT_TOP_LEFT,
																			pImageBuffer,
																			(ThermalPrinterDotsInLine / 8),
																			LineHeight);
								if ( ThermalPrinterImageSize > 0 )
								{
									printf( "Termal Printer Image Size = %d Byte\n", ThermalPrinterImageSize );
//									print_hex_dump( pImageBuffer, ThermalPrinterImageSize );
									if ( thermal_printer_print( ThermalPrinter, pImageBuffer, ThermalPrinterImageSize ) < 0 )
									{
										printf( "Fail to Print Image Size = %d Byte\n", ThermalPrinterImageSize );
									}
									printf( "Print Termal Printer Image Size = %d Byte\n", ThermalPrinterImageSize );
								}

								/* clear Line area.. if it needed */
								memset( pImageBuffer, 0, ((LineHeight * ThermalPrinterDotsInLine) / 8 ) );
								ThermalPrinterImageSize = ui_printer_string( pUI,
/*																			TEST_DISPLAY_STRING,*/
																			pThermapPrinterTestString,
																			UI_TEXT_LAYOUT_TOP_LEFT,
																			pImageBuffer,
																			(ThermalPrinterDotsInLine / 8),
																			LineHeight);
								if ( ThermalPrinterImageSize > 0 )
								{
									printf( "Termal Printer Image Size = %d Byte\n", ThermalPrinterImageSize );
	//								print_hex_dump( pImageBuffer, ThermalPrinterImageSize );
									if ( thermal_printer_print( ThermalPrinter, pImageBuffer, ThermalPrinterImageSize ) < 0 )
									{
										printf( "Fail to Print Image Size = %d Byte\n", ThermalPrinterImageSize );
									}
									printf( "Print Termal Printer Image Size = %d Byte\n", ThermalPrinterImageSize );
								}
							}
						}
					}

					thermal_printer_paper_throw( ThermalPrinter, 150/*Line*/ );
#else	/* TEST_THERMAL_PRINTER */
					if( Brightness != 0 )
					{
						Brightness --;
						if( bright_set(Brightness) != 0 )
						{
							printf("Fail to bright_set\n");
						}
						printf("bright +\n");
					}
#endif	/* TEST_THERMAL_PRINTER */
				}
				printf("Key code : KEY_F7 (0x%X)\n", KeyCode);
				break;
			case	KEY_F8:
				printf("Key code : KEY_F8 - Side Key Up or Feed (0x%X)\n", KeyCode);
				if ( IsReleased == true )
				{	/* Key Released */
					key_back_light( true/*On*/ );
				}
				break;
			case	KEY_F9:
				printf("Key code : KEY_F9 - Side Key Down or Select (0x%X)\n", KeyCode);
				if ( IsReleased == true )
				{	/* Key Released */
					key_back_light( false/*Off*/ );
				}
				break;
			case	KEY_F10:
				printf("Key code : KEY_F10 - Scan Key or SetUp (0x%X)\n", KeyCode);
				break;
			default:
//				printf("Key code : (0x%X)\n", KeyCode);
				break;
			}
		}

		if ( IsInLoop == 0 )
		{
			printf( "Exit Main Loop\n" );
		}
	} /* while (IsInLoop)*/

#ifdef	TEST_LTE_MODEM
	lte_on_off_switch( false/*true=on, false=Off*/ );
#endif	/* TEST_LTE_MODEM */

	printf( "Close opend system\n" );
	if ( mmd1100_close() != 0 )
	{
		printf("Fail to mmd1100_close\n");
	}
	else
	{
		printf("OK to mmd1100_close\n");
	}
	if ( buzzer_close() < 0 )
	{
		printf("Fail to buzzer_close\n");
	}
	/* clean up */
	ui_release( pUI );
#ifdef	TEST_THERMAL_PRINTER
	thermal_printer_close( ThermalPrinter );
#endif	/* TEST_THERMAL_PRINTER */

	return	0;
}

API Header File

#ifndef	__UI_H__
#define	__UI_H__

#include	<stdint.h>		/* uint??_t */
//#include	<stdbool.h>		/* Bool */
#include	"directfb/directfb.h"	/* 항상 UI.h 와 함께 UI.h 보다 먼저 */


typedef	struct
{
	uint8_t	R;
	uint8_t	G;
	uint8_t	B;
	uint8_t	Alpha;
} UIcolor_t;

typedef	enum
{
	UI_TEXT_LAYOUT_NONE = 0,
	UI_TEXT_LAYOUT_TOP_LEFT,
	UI_TEXT_LAYOUT_TOP_CENTER,
	UI_TEXT_LAYOUT_TOP_RIGHT,
	UI_TEXT_LAYOUT_BOTTOM_LEFT,
	UI_TEXT_LAYOUT_BOTTOM_CENTER,
	UI_TEXT_LAYOUT_BOTTOM_RIGHT,
	UI_TEXT_LAYOUT_MIDDLE_LEFT,
	UI_TEXT_LAYOUT_MIDDLE_CENTER,
	UI_TEXT_LAYOUT_MIDDLE_RIGHT,
	UI_TEXT_LAYOUT_OUTLINE_TOP_LEFT,
	UI_TEXT_LAYOUT_OUTLINE_TOP_CENTER,
	UI_TEXT_LAYOUT_OUTLINE_TOP_RIGHT,
	UI_TEXT_LAYOUT_OUTLINE_BOTTOM_LEFT,
	UI_TEXT_LAYOUT_OUTLINE_BOTTOM_CENTER,
	UI_TEXT_LAYOUT_OUTLINE_BOTTOM_RIGHT,
	UI_TEXT_LAYOUT_OUTLINE_MIDDLE_LEFT,
	UI_TEXT_LAYOUT_OUTLINE_MIDDLE_CENTER,
	UI_TEXT_LAYOUT_OUTLINE_MIDDLE_RIGHT,
} UItextLayout_t;


#define	UI_DRIVER_MESSAGE_ERROR	//	Must be Defined
//#define	UI_DRIVER_MESSAGE_DEBUG
//#define	UI_DRIVER_MESSAGE_INFO
//#define	UI_DRIVER_MESSAGE_KEY_EVENT_INFO


extern	int	ui_initialize(void **pUI, uint32_t Rotate);
extern	int	ui_release(void *pUI);
extern	int	ui_change_font(void *pUI, char *pFontFile, int FontSize);

/*
//	아래와 같은 형태로 Layout이 나타난다.
//	-----------------------------------------
//	|UI_TEXT_LAYOUT_TOP_LEFT                |
//	|                                       |
//	|     UI_TEXT_LAYOUT_MIDDLE_CENTER      |
//	|                                       |
//	|            UI_TEXT_LAYOUT_BOTTOM_RIGHT|
//	-----------------------------------------
*/
extern	int	ui_draw_string(void *pUI, UIcolor_t Color,
					uint32_t X, uint32_t Y, uint32_t W, uint32_t H,
					char *pString,
					UItextLayout_t UItextLayout);

extern	int	ui_draw_line(void *pUI, UIcolor_t Color,
					uint32_t X1, uint32_t Y1, uint32_t X2, uint32_t Y2);

extern	int	ui_draw_rectangle(void *pUI, UIcolor_t Color,
					uint32_t X, uint32_t Y, uint32_t W, uint32_t H);

extern	int	ui_fill_rectangle(void *pUI, UIcolor_t Color,
					uint32_t X, uint32_t Y, uint32_t W, uint32_t H);

extern	int	ui_clear_screen(void *pUI);

/*
	jpg
	png
	gif
*/
extern	int	ui_draw_image(void *pUI, char *pImageFile, uint32_t X, uint32_t Y);

/*
	0: No key input or Parameter Error
	1: Key is inputed
*/
extern	int	ui_key_is_inputed(void *pUI, uint32_t MiliSecondWaitTimeout);

/*
	0: OK
	-1: Error
*/
extern	int	ui_key_get_code(void *pUI, uint32_t *pKeyCode, bool *pIsReleased);


extern	int	ui_printer_create_surface(void *pUI, uint32_t SurfaceWidth, uint32_t SurfaceHeight);
extern	int	ui_printer_font_set(void *pUI, char *pFontFile, int FontSize);
extern	int	ui_printer_font_get_line_height(void *pUI, uint32_t *pLineHeight);
extern	int	ui_printer_string(void *pUI,
						char *pString,
						UItextLayout_t UItextLayout,
						uint8_t *pImageBuffer,
						uint32_t ByteSizeOfImageBufferWidth,
						uint32_t ByteSizeOfImageBufferHeight);


#endif	/* __UI_H__ */

API Source File

#include	<stdio.h>
#include	<stdint.h>		/* uint??_t */
#include	<string.h>		/* for memset */
//#include	<unistd.h>		/* for open/close .. */
//#include	<fcntl.h>		/* for O_RDWR */
//#include	<sys/ioctl.h>	/* for ioctl */
//#include	<sys/mman.h>	/* for mmap */
//#include	<linux/fb.h>	/* for fb_var_screeninfo, FBIOGET_VSCREENINFO */
#include	<linux/input.h>
#include	<poll.h>
//#include	<sys/fcntl.h>		/* for O_RDWR */

#include	<unistd.h>		/* sleep */

#include	"directfb/directfb.h"
#include	"UI.h"
/*
Surface는 이미지의 픽셀데이터가 특정 픽셀 형식으로 저장되는 메모리의 예약 영역임.

*/

#ifdef	UI_DRIVER_MESSAGE_DEBUG
	#define	UI_DEBUG(fmt, args ...)	printf("DEBUG:%s(%d): " fmt, __FUNCTION__,__LINE__, ## args)
#else
	#define	UI_DEBUG(fmt, args ...)	{}
#endif	/* UI_DRIVER_MESSAGE_DEBUG */

#ifdef	UI_DRIVER_MESSAGE_ERROR
	#define	UI_ERROR(fmt, args ...)	printf("ERROR:%s(%d): " fmt, __FUNCTION__,__LINE__, ## args)
#else
	#define	UI_ERROR(fmt, args ...)	{}
#endif	/* UI_DRIVER_DEBUG_MESSAGE */

#ifdef	UI_DRIVER_MESSAGE_INFO
	#define	UI_INFO(fmt, args ...)	printf("INFOs:%s(%d): " fmt, __FUNCTION__,__LINE__, ## args)
#else
	#define	UI_INFO(fmt, args ...)	{}
#endif	/* UI_DRIVER_DEBUG_MESSAGE */

#define	DEFAULT_FONT_FILE	"D2Coding.ttf"
#define	DEFAULT_FONT_SIZE	22

typedef	struct
{
	uint32_t	X;
	uint32_t	Y;
} UIposition_t;

typedef	struct
{
	uint32_t				MagicNumber;

	IDirectFB *				pDirectFb;

	IDirectFBInputDevice *	pInputDevice;
	IDirectFBEventBuffer *	pEventBuffer;

	IDirectFBSurface *		pPrimarySurface;	/* primary surface - Base Screen */

	int						ScreenWidth;
	int						ScreenHeight;

	IDirectFBFont *			pFont;
	char *					pFontFile;
	int						FontSize;

	uint32_t				Rotate;
	uint32_t				UserScreenWidth;
	uint32_t				UserScreenHeight;


	IDirectFBSurface *		pPrinterSurface;	/* Printer surface */
	uint32_t				PrinterSurfaceWidth;
	uint32_t				PrinterSurfaceHeight;

	IDirectFBFont *			pPrinterFont;
	char *					pPrinterFontFile;
	int						PrinterFontSize;
//	uint32_t				PrintedImageWidth;
	uint32_t				PrintedLineHeight;
} UIcontext_t;

static	UIcontext_t		UIcontext = {0};
static	UIcontext_t *	pUIcontext = (UIcontext_t *)0;

int		ui_initialize(void **pUI, uint32_t Rotate)
{
	DFBSurfaceDescription	SurfaceDescription;
	DFBFontDescription		FontDescription;

	if ( ( pUI == (void **)0 ) || ( ( Rotate % 90 ) != 0 ) )
	{
		UI_ERROR( "Error in Input Paramter\n" );
		return	-1;
	}
	Rotate %= 360;

	if ( pUIcontext != (UIcontext_t *)0 )
	{
		UI_DEBUG( "Already initialized\n" );
		*pUI = (void *)pUIcontext;
		return	0;
	}

	UI_INFO( "Initialize Direct FB\n" );
	if ( DirectFBInit( 0, 0 ) != DFB_OK )
	{
		UI_ERROR( "Error in DirectFBInit()\n" );
		goto	UI_INITIALIZE_ERROR_IN_INIT_DIRECT_FB;
	}

	UI_INFO( "Create Super Interface\n" );
	if ( DirectFBCreate( &UIcontext.pDirectFb ) != DFB_OK )
	{
		UI_ERROR( "Error in DirectFBCreate()\n" );
		goto	UI_INITIALIZE_ERROR_IN_CREATE_FB;
	}

	UI_INFO( "Create Input Device\n" );
	if ( UIcontext.pDirectFb->GetInputDevice( UIcontext.pDirectFb, DIDID_KEYBOARD, &UIcontext.pInputDevice ) != DFB_OK )
	{
		UI_ERROR( "Error in GetInputDevice()\n" );
		goto	UI_INITIALIZE_ERROR_IN_CREATE_INPUT_DEVICE;
	}

	UI_INFO( "Create Event Buffer\n" );
	if ( UIcontext.pInputDevice->CreateEventBuffer( UIcontext.pInputDevice, &UIcontext.pEventBuffer ) != DFB_OK )
	{
		UI_ERROR( "Error in CreateEventBuffer()\n" );
		goto	UI_INITIALIZE_ERROR_IN_CREATE_EVENT_BUFFER;
	}

	UI_INFO( "Set Cooperative Level - to full screen\n" );
	if ( UIcontext.pDirectFb->SetCooperativeLevel( UIcontext.pDirectFb, DFSCL_FULLSCREEN ) != DFB_OK )
	{
		UI_ERROR( "Error in SetCooperativeLevel()\n ");
		goto	UI_INITIALIZE_ERROR_IN_SET_COOPERATIVE_LEVEL;
	}

	/* set flags */
	SurfaceDescription.flags = DSDESC_CAPS;
	SurfaceDescription.caps = DSCAPS_PRIMARY | DSCAPS_FLIPPING;
	UI_INFO( "Create Surface - Prime\n" );
	if ( UIcontext.pDirectFb->CreateSurface( UIcontext.pDirectFb, &SurfaceDescription, &UIcontext.pPrimarySurface ) != DFB_OK )
	{
		UI_ERROR( "Error in CreateSurface()\n" );
		goto	UI_INITIALIZE_ERROR_IN_CREATE_PRIME_SURFACE;
	}

	UI_INFO( "Get Surface Size\n" );
	if ( UIcontext.pPrimarySurface->GetSize( UIcontext.pPrimarySurface, &UIcontext.ScreenWidth, &UIcontext.ScreenHeight ) != DFB_OK )
	{
		UI_ERROR( "Error in GetSize()\n");
		goto	UI_INITIALIZE_ERROR_IN_GET_PRIME_SURFACE_SIZE;
	}
	UI_INFO( "  Prime Surface : Physical Width = %d, Physical Height= %d\n", UIcontext.ScreenWidth, UIcontext.ScreenHeight );

	UI_INFO( "Clear Surface\n" );
	if ( UIcontext.pPrimarySurface->FillRectangle( UIcontext.pPrimarySurface, 0, 0, UIcontext.ScreenWidth, UIcontext.ScreenHeight ) != DFB_OK )
	{
		UI_ERROR( "Error in FillRectangle() to clear prime surface\n");
		goto	UI_INITIALIZE_ERROR_IN_CLEAR_SURFACE;
	}
	if ( UIcontext.pPrimarySurface->Flip( UIcontext.pPrimarySurface, NULL, 0 ) != DFB_OK )
	{
		UI_ERROR( "Error in Flip() to clear prime surface\n");
		goto	UI_INITIALIZE_ERROR_IN_FLIP_TO_CLEAR_SURFACE;
	}

	UIcontext.FontSize = DEFAULT_FONT_SIZE;
	UIcontext.pFontFile = DEFAULT_FONT_FILE;

	UI_INFO( "Create Font\n" );
	FontDescription.flags      = DFDESC_HEIGHT | DFDESC_ATTRIBUTES;
	FontDescription.height     = UIcontext.FontSize;
	FontDescription.attributes = DFFA_MONOCHROME;	//	DFFA_NONE
	if ( UIcontext.pDirectFb->CreateFont( UIcontext.pDirectFb, UIcontext.pFontFile, &FontDescription, &UIcontext.pFont ) != DFB_OK )
	{
		UI_ERROR( "Error in CreateFont()\n");
		goto	UI_INITIALIZE_ERROR_IN_CREATE_FONT;
	}

	UIcontext.MagicNumber = 0x1828128;
	UIcontext.Rotate = Rotate;
	if ( ( UIcontext.Rotate == 90) || ( UIcontext.Rotate == 270) )
	{
		UIcontext.UserScreenWidth  = UIcontext.ScreenHeight;
		UIcontext.UserScreenHeight = UIcontext.ScreenWidth;
	}
	else
	{
		UIcontext.UserScreenWidth  = UIcontext.ScreenWidth;
		UIcontext.UserScreenHeight = UIcontext.ScreenHeight;
	}
	pUIcontext = &UIcontext;
	*pUI = (void *)pUIcontext;

	UIcontext.pPrinterSurface = (IDirectFBSurface *)0;
	UIcontext.pPrinterFont = (IDirectFBFont *)0;

	UI_INFO( "Initialized\n" );

	return	0;

UI_INITIALIZE_ERROR_IN_CREATE_FONT:
UI_INITIALIZE_ERROR_IN_FLIP_TO_CLEAR_SURFACE:
UI_INITIALIZE_ERROR_IN_CLEAR_SURFACE:
UI_INITIALIZE_ERROR_IN_GET_PRIME_SURFACE_SIZE:
	UIcontext.pPrimarySurface->Release( UIcontext.pPrimarySurface );

UI_INITIALIZE_ERROR_IN_CREATE_PRIME_SURFACE:
UI_INITIALIZE_ERROR_IN_SET_COOPERATIVE_LEVEL:
	UIcontext.pEventBuffer->Release( UIcontext.pEventBuffer );

UI_INITIALIZE_ERROR_IN_CREATE_EVENT_BUFFER:
	UIcontext.pInputDevice->Release( UIcontext.pInputDevice );

UI_INITIALIZE_ERROR_IN_CREATE_INPUT_DEVICE:
	UIcontext.pDirectFb->Release( UIcontext.pDirectFb );

UI_INITIALIZE_ERROR_IN_CREATE_FB:
UI_INITIALIZE_ERROR_IN_INIT_DIRECT_FB:

	return	-2;
}


int		ui_release(void *pUI)
{
	if ( ( pUI == (void *)0 ) || ( pUI != (void *)pUIcontext ) )
	{
		return	-1;
	}

	if ( UIcontext.MagicNumber != 0x1828128 )
	{
		return	-1;
	}

	UIcontext.MagicNumber = 0;

	if ( UIcontext.pPrinterSurface != (IDirectFBSurface *)0 )
	{
printf ( "Printer Surface Release\n" );
		UIcontext.pPrinterSurface->Release( UIcontext.pPrinterSurface );
	}
	if ( UIcontext.pPrinterFont != (IDirectFBFont *)0 )
	{
printf ( "Printer Font Release\n" );
		UIcontext.pPrinterFont->Release( UIcontext.pPrinterFont );
	}

	UIcontext.pFont->Release( UIcontext.pFont );
	UIcontext.pPrimarySurface->Release( UIcontext.pPrimarySurface );
	UIcontext.pEventBuffer->Release( UIcontext.pEventBuffer );
	UIcontext.pInputDevice->Release( UIcontext.pInputDevice );
	UIcontext.pDirectFb->Release( UIcontext.pDirectFb );

	pUIcontext = (UIcontext_t *)0;
	memset( &UIcontext, 0, sizeof(UIcontext_t) );

	return	0;
}

int		ui_change_font(void *pUI, char *pFontFile, int FontSize)
{
	DFBFontDescription	FontDescription;
	IDirectFBFont *		pNewFont;

	if ( ( pUI == (void *)0 ) || ( pUI != (void *)pUIcontext ) )
	{
		return	-1;
	}

	if ( UIcontext.MagicNumber != 0x1828128 )
	{
		return	-1;
	}

	FontDescription.flags      = DFDESC_HEIGHT | DFDESC_ATTRIBUTES;
	FontDescription.height     = FontSize;
	FontDescription.attributes = DFFA_MONOCHROME;	//	DFFA_NONE
	if ( UIcontext.pDirectFb->CreateFont( UIcontext.pDirectFb, pFontFile, &FontDescription, &pNewFont ) != DFB_OK )
	{
		UI_ERROR( "Error in CreateFont()\n");
		return	-1;
	}

	if ( UIcontext.pFont->Release( UIcontext.pFont ) != DFB_OK )
	{
		UI_DEBUG( "Error in Release() for release old font.. using old font\n");
		pNewFont->Release( pNewFont );
		return	-2;
	}

	UIcontext.pFont = pNewFont;
	UIcontext.FontSize = FontSize;
	UIcontext.pFontFile = pFontFile;

	return	0;
}

uint32_t	ui_make_text_flag(UItextLayout_t UItextLayout)
{
	uint32_t	Flag;

	Flag = DSTF_NONE;
	switch ( UItextLayout )
	{
	case	UI_TEXT_LAYOUT_TOP_LEFT:
		Flag += DSTF_TOP;
		Flag += DSTF_LEFT;
		break;
	case	UI_TEXT_LAYOUT_TOP_CENTER:
		Flag += DSTF_TOP;
		Flag += DSTF_CENTER;
		break;
	case	UI_TEXT_LAYOUT_TOP_RIGHT:
		Flag += DSTF_TOP;
		Flag += DSTF_RIGHT;
		break;
	case	UI_TEXT_LAYOUT_BOTTOM_LEFT:
		Flag += DSTF_BOTTOM;
		Flag += DSTF_LEFT;
		break;
	case	UI_TEXT_LAYOUT_BOTTOM_CENTER:
		Flag += DSTF_BOTTOM;
		Flag += DSTF_CENTER;
		break;
	case	UI_TEXT_LAYOUT_BOTTOM_RIGHT:
		Flag += DSTF_BOTTOM;
		Flag += DSTF_RIGHT;
		break;
	case	UI_TEXT_LAYOUT_MIDDLE_LEFT:
		Flag += DSTF_LEFT;
		break;
	case	UI_TEXT_LAYOUT_MIDDLE_CENTER:
		Flag += DSTF_CENTER;
		break;
	case	UI_TEXT_LAYOUT_MIDDLE_RIGHT:
		Flag += DSTF_RIGHT;
		break;
	case	UI_TEXT_LAYOUT_OUTLINE_TOP_LEFT:
		Flag += DSTF_OUTLINE;
		Flag += DSTF_TOP;
		Flag += DSTF_LEFT;
		break;
	case	UI_TEXT_LAYOUT_OUTLINE_TOP_CENTER:
		Flag += DSTF_OUTLINE;
		Flag += DSTF_TOP;
		Flag += DSTF_CENTER;
		break;
	case	UI_TEXT_LAYOUT_OUTLINE_TOP_RIGHT:
		Flag += DSTF_TOP;
		Flag += DSTF_RIGHT;
		Flag += DSTF_OUTLINE;
		break;
	case	UI_TEXT_LAYOUT_OUTLINE_BOTTOM_LEFT:
		Flag += DSTF_OUTLINE;
		Flag += DSTF_BOTTOM;
		Flag += DSTF_LEFT;
		break;
	case	UI_TEXT_LAYOUT_OUTLINE_BOTTOM_CENTER:
		Flag += DSTF_OUTLINE;
		Flag += DSTF_BOTTOM;
		Flag += DSTF_CENTER;
		break;
	case	UI_TEXT_LAYOUT_OUTLINE_BOTTOM_RIGHT:
		Flag += DSTF_OUTLINE;
		Flag += DSTF_BOTTOM;
		Flag += DSTF_RIGHT;
		break;
	case	UI_TEXT_LAYOUT_OUTLINE_MIDDLE_LEFT:
		Flag += DSTF_OUTLINE;
		Flag += DSTF_LEFT;
		break;
	case	UI_TEXT_LAYOUT_OUTLINE_MIDDLE_CENTER:
		Flag += DSTF_OUTLINE;
		Flag += DSTF_CENTER;
		break;
	case	UI_TEXT_LAYOUT_OUTLINE_MIDDLE_RIGHT:
		Flag += DSTF_OUTLINE;
		Flag += DSTF_RIGHT;
		break;
	case	UI_TEXT_LAYOUT_NONE:
	default:
		break;
	}

	return	Flag;
}

UIposition_t	ui_make_text_draw_position(UItextLayout_t UItextLayout,
											uint32_t X,
											uint32_t Y,
											uint32_t W,
											uint32_t H,
											uint32_t Rotate)
{
	UIposition_t	Position;
	uint32_t		Temp;

	switch ( UItextLayout )
	{
	case	UI_TEXT_LAYOUT_TOP_LEFT:
	case	UI_TEXT_LAYOUT_OUTLINE_TOP_LEFT:
		Position.X = X;
		Position.Y = Y;
		break;
	case	UI_TEXT_LAYOUT_OUTLINE_TOP_CENTER:
	case	UI_TEXT_LAYOUT_TOP_CENTER:
		Position.X = X + ( W >> 1 );
		Position.Y = Y;
		break;
	case	UI_TEXT_LAYOUT_OUTLINE_TOP_RIGHT:
	case	UI_TEXT_LAYOUT_TOP_RIGHT:
		Position.X = X + W;
		Position.Y = Y;
		break;
	case	UI_TEXT_LAYOUT_OUTLINE_BOTTOM_LEFT:
	case	UI_TEXT_LAYOUT_BOTTOM_LEFT:
		Position.X = X;
		Position.Y = Y + H;
		break;
	case	UI_TEXT_LAYOUT_OUTLINE_BOTTOM_CENTER:
	case	UI_TEXT_LAYOUT_BOTTOM_CENTER:
		Position.X = X + ( W >> 1 );
		Position.Y = Y + H;
		break;
	case	UI_TEXT_LAYOUT_OUTLINE_BOTTOM_RIGHT:
	case	UI_TEXT_LAYOUT_BOTTOM_RIGHT:
		Position.X = X + W;
		Position.Y = Y + H;
		break;

	case	UI_TEXT_LAYOUT_OUTLINE_MIDDLE_CENTER:
	case	UI_TEXT_LAYOUT_MIDDLE_CENTER:
		Position.X = X + ( W >> 1 );
		Position.Y = Y + ( H >> 1 );
		break;
	case	UI_TEXT_LAYOUT_OUTLINE_MIDDLE_RIGHT:
	case	UI_TEXT_LAYOUT_MIDDLE_RIGHT:
		Position.X = X + W;
		Position.Y = Y + ( H >> 1 );
		break;

	case	UI_TEXT_LAYOUT_OUTLINE_MIDDLE_LEFT:
	case	UI_TEXT_LAYOUT_MIDDLE_LEFT:
	case	UI_TEXT_LAYOUT_NONE:
	default:
		Position.X = X;
		Position.Y = Y + ( H >> 1 );
		break;
	}
	if ( ( Rotate == 90 ) || ( Rotate == 270 ) )
	{
		Temp = Position.X;
		Position.X = Position.Y;
		Position.Y = Temp;
	}

	return	Position;
}

static	int	ui_draw_update(IDirectFBSurface *pPrimarySurface, uint32_t Rotate)
{
	/* update surface */
	if ( Rotate == 90 )
	{
		if ( pPrimarySurface->SetBlittingFlags( pPrimarySurface, DSBLIT_ROTATE90 ) != DFB_OK )
		{
			return	-3;
		}
	}
	else if ( Rotate == 180 )
	{
		if ( pPrimarySurface->SetBlittingFlags( pPrimarySurface, DSBLIT_ROTATE180 ) != DFB_OK )
		{
			return	-3;
		}
	}
	else if ( Rotate == 270 )
	{
		if ( pPrimarySurface->SetBlittingFlags( pPrimarySurface, DSBLIT_ROTATE270 ) != DFB_OK )
		{
			return	-3;
		}
	}

	if ( pPrimarySurface->Flip( pPrimarySurface, NULL, 0) != DFB_OK )
	{
		return	-3;
	}

	if ( Rotate != 0 )
	{
		if ( pPrimarySurface->SetBlittingFlags( pPrimarySurface, DSBLIT_NOFX ) != DFB_OK )
		{
			return	-3;
		}
	}

	return	0;
}

int		ui_draw_string(void *pUI,
					UIcolor_t Color,
					uint32_t X,
					uint32_t Y,
					uint32_t W,
					uint32_t H,
					char *pString,
					UItextLayout_t UItextLayout)
{
	int				DisplayWidth;
	int				DisplayHeight;
	UIposition_t	Position;

	if ( ( pUI == (void *)0 ) || ( pUI != (void *)pUIcontext ) || ( pString == (char *)0 ) )
	{
		UI_ERROR( "Input Parameter\n" );
		return	-1;
	}

	if ( UIcontext.MagicNumber != 0x1828128 )
	{
		UI_ERROR( "Magic Number\n" );
		return	-1;
	}

	if ( UIcontext.pFont->GetStringWidth( UIcontext.pFont, pString, -1/*bytes*/, &DisplayWidth) != DFB_OK )
	{
		UI_ERROR( "Get String Width\n" );
		return	-3;
	}
	UI_INFO( "String Width = %d\n", DisplayWidth );

	if ( UIcontext.pFont->GetHeight( UIcontext.pFont, &DisplayHeight ) != DFB_OK )
	{
		UI_ERROR( "Get String Height\n" );
		return	-3;
	}
	UI_INFO( "String Height = %d\n", DisplayHeight );

	if ( ( DisplayWidth > W ) || ( DisplayHeight > H ) )
	{
		UI_ERROR( "DisplayWidth(%d) > W(%d) or DisplayHeight(%d) > H(%d)\n", DisplayWidth, W, DisplayHeight, H );
		return	-1;
	}
	if ( ( UIcontext.UserScreenWidth < ( W + X ) ) || ( UIcontext.UserScreenHeight < ( H + Y ) ) )
	{
		UI_ERROR( "UserScreenWidth(%d) < (W + X)(%d) or UIcontext.UserScreenHeight(%d) < ( H + Y )(%d)\n",
				UIcontext.UserScreenWidth,
				( W + X ),
				UIcontext.UserScreenHeight,
				( H + Y ) );
		return	-1;
	}

	if ( UIcontext.pPrimarySurface->SetFont( UIcontext.pPrimarySurface, UIcontext.pFont ) != DFB_OK )
	{
		UI_ERROR( "Set Font\n" );
		return	-3;
	}
	UI_INFO( "Set Font OK\n" );

	if ( UIcontext.pPrimarySurface->SetColor( UIcontext.pPrimarySurface, Color.B, Color.G, Color.R, Color.Alpha ) != DFB_OK )
	{
		UI_ERROR( "Set Color\n" );
		return	-3;
	}
	UI_INFO( "Set Color OK\n" );
	
	Position = ui_make_text_draw_position( UItextLayout, X, Y, W, H, UIcontext.Rotate );
	UI_INFO( "Position : X = %d, Y= %d\n", Position.X, Position.Y );
	if ( UIcontext.pPrimarySurface->DrawString( UIcontext.pPrimarySurface, pString, -1/*Bytes*/, Position.X, Position.Y, ui_make_text_flag( UItextLayout )/*Flasg*/ ) != DFB_OK )
	{
		UI_ERROR( "Draw\n" );
		return	-3;
	}
	UI_INFO( "Draw OK\n" );

	/* update surface */
	return	ui_draw_update( UIcontext.pPrimarySurface, UIcontext.Rotate);
}

int		ui_draw_line(void *pUI,
					UIcolor_t Color,
					uint32_t X1,
					uint32_t Y1,
					uint32_t X2,
					uint32_t Y2)
{
	if ( ( pUI == (void *)0 ) || ( pUI != (void *)pUIcontext ) )
	{
		return	-1;
	}

	if ( UIcontext.MagicNumber != 0x1828128 )
	{
		return	-1;
	}

	if ( ( UIcontext.UserScreenWidth <= X1 ) || ( UIcontext.UserScreenHeight <= Y1 )
	 || ( UIcontext.UserScreenWidth <= X2 ) || ( UIcontext.UserScreenHeight <= Y2 ) )
	{
		return	-2;
	}

	if ( UIcontext.pPrimarySurface->SetColor( UIcontext.pPrimarySurface, Color.B, Color.G, Color.R, Color.Alpha ) != DFB_OK )
	{
		return	-3;
	}
	
	if ( UIcontext.pPrimarySurface->DrawLine( UIcontext.pPrimarySurface, X1, Y1, X2, Y2 ) != DFB_OK )
	{
		return	-3;
	}

	/* update surface */
	return	ui_draw_update( UIcontext.pPrimarySurface, UIcontext.Rotate);
}


int		ui_draw_rectangle(void *pUI,
					UIcolor_t Color,
					uint32_t X,
					uint32_t Y,
					uint32_t W,
					uint32_t H)
{
	if ( ( pUI == (void *)0 ) || ( pUI != (void *)pUIcontext ) )
	{
		return	-1;
	}

	if ( UIcontext.MagicNumber != 0x1828128 )
	{
		return	-1;
	}

	if ( ( UIcontext.UserScreenWidth <= ( W + X ) ) || ( UIcontext.UserScreenHeight <= ( H + Y ) ) )
	{
		return	-2;
	}

	if ( UIcontext.pPrimarySurface->SetColor( UIcontext.pPrimarySurface, Color.B, Color.G, Color.R, Color.Alpha ) != DFB_OK )
	{
		return	-3;
	}
	
	if ( UIcontext.pPrimarySurface->DrawRectangle( UIcontext.pPrimarySurface, X, Y, W, H ) != DFB_OK )
	{
		return	-3;
	}

	/* update surface */
	return	ui_draw_update( UIcontext.pPrimarySurface, UIcontext.Rotate);
}


int		ui_fill_rectangle(void *pUI,
					UIcolor_t Color,
					uint32_t X,
					uint32_t Y,
					uint32_t W,
					uint32_t H)
{
	if ( ( pUI == (void *)0 ) || ( pUI != (void *)pUIcontext ) )
	{
		return	-1;
	}

	if ( UIcontext.MagicNumber != 0x1828128 )
	{
		return	-1;
	}

	if ( ( UIcontext.UserScreenWidth <= ( W + X ) ) || ( UIcontext.UserScreenHeight <= ( H + Y ) ) )
	{
		return	-2;
	}

	if ( UIcontext.pPrimarySurface->SetColor( UIcontext.pPrimarySurface, Color.B, Color.G, Color.R, Color.Alpha ) != DFB_OK )
	{
		return	-3;
	}
	
	if ( UIcontext.pPrimarySurface->FillRectangle( UIcontext.pPrimarySurface, X, Y, W, H ) != DFB_OK )
	{
		return	-3;
	}

	/* update surface */
	return	ui_draw_update( UIcontext.pPrimarySurface, UIcontext.Rotate);
}

int		ui_clear_screen(void *pUI)
{
	if ( ( pUI == (void *)0 ) || ( pUI != (void *)pUIcontext ) )
	{
		return	-1;
	}

	if ( UIcontext.MagicNumber != 0x1828128 )
	{
		return	-1;
	}

	if ( UIcontext.pPrimarySurface->SetColor( UIcontext.pPrimarySurface, 0, 0, 0, 0xFF ) != DFB_OK )
	{
		return	-3;
	}
	
	if ( UIcontext.pPrimarySurface->FillRectangle( UIcontext.pPrimarySurface, 0, 0, UIcontext.ScreenWidth, UIcontext.ScreenHeight ) != DFB_OK )
	{
		return	-3;
	}

	/* update surface */
	return	ui_draw_update( UIcontext.pPrimarySurface, UIcontext.Rotate);
}

/*
	jpg
	png
	gif
*/
int		ui_draw_image(void *pUI,
					char *pImageFile,
					uint32_t X,
					uint32_t Y)
{
	IDirectFBSurface *		pImageSurface;	/* Image surface */
	IDirectFBImageProvider *pImageProvider;	/* */
	DFBSurfaceDescription	SurfaceDescription;

	if ( ( pUI == (void *)0 ) || ( pUI != (void *)pUIcontext ) )
	{
		return	-1;
	}

	if ( UIcontext.MagicNumber != 0x1828128 )
	{
		return	-1;
	}

	/* Create image provider */
	if ( UIcontext.pDirectFb->CreateImageProvider( UIcontext.pDirectFb, pImageFile, &pImageProvider ) != DFB_OK )
	{
		goto	UI_DRAW_IMAGE_ERROR_IN_CREATE_IMAGE_PROVIDER;
	}

	if ( pImageProvider->GetSurfaceDescription( pImageProvider, &SurfaceDescription ) != DFB_OK )
	{
		goto	UI_DRAW_IMAGE_ERROR_IN_GET_SURFACE_DESCRIPTION;
	}

	if ( UIcontext.pDirectFb->CreateSurface( UIcontext.pDirectFb, &SurfaceDescription, &pImageSurface) != DFB_OK )
	{
		goto	UI_DRAW_IMAGE_ERROR_IN_CREATE_SURFACE;
	}

	if ( pImageProvider->RenderTo( pImageProvider, pImageSurface, NULL) != DFB_OK )
	{
		goto	UI_DRAW_IMAGE_ERROR_IN_RANDER;
	}

	if ( UIcontext.pPrimarySurface->Blit( UIcontext.pPrimarySurface, pImageSurface, NULL, X, Y) != DFB_OK )
	{
		goto	UI_DRAW_IMAGE_ERROR_IN_BLIT;
	}

	/* update surface */
	if ( ui_draw_update( UIcontext.pPrimarySurface, UIcontext.Rotate ) != 0 )
	{
		goto	UI_DRAW_IMAGE_ERROR_IN_UPDATE;
	}

UI_DRAW_IMAGE_ERROR_IN_UPDATE:
UI_DRAW_IMAGE_ERROR_IN_BLIT:
UI_DRAW_IMAGE_ERROR_IN_RANDER:

	pImageSurface->Release( pImageSurface );

UI_DRAW_IMAGE_ERROR_IN_CREATE_SURFACE:
UI_DRAW_IMAGE_ERROR_IN_GET_SURFACE_DESCRIPTION:

	pImageProvider->Release( pImageProvider );

UI_DRAW_IMAGE_ERROR_IN_CREATE_IMAGE_PROVIDER:

	return -2;
}


/*
	0: No key input or Parameter Error
	1: Key is inputed
*/
int		ui_key_is_inputed(void *pUI, uint32_t MiliSecondWaitTimeout)
{
	if ( ( pUI == (void *)0 ) || ( pUI != (void *)pUIcontext ) )
	{
		return	-1;
	}

	if ( UIcontext.MagicNumber != 0x1828128 )
	{
		return	-1;
	}


	if ( /*( UIcontext.pEventBuffer == (IDirectFBEventBuffer *)0 ) ||*/ ( MiliSecondWaitTimeout == 0 ) )
	{
		return	-1;
	}

	if ( UIcontext.pEventBuffer->WaitForEventWithTimeout( UIcontext.pEventBuffer, 0, MiliSecondWaitTimeout ) == DFB_TIMEOUT )
	{
		return	0;
	}

	return	1;
}

/*
	0: OK
	-1: Error
*/
int		ui_key_get_code(void *pUI, uint32_t *pKeyCode, bool *pIsReleased)
{
	if ( ( pUI == (void *)0 ) || ( pUI != (void *)pUIcontext ) )
	{
		return	-1;
	}

	if ( UIcontext.MagicNumber != 0x1828128 )
	{
		return	-1;
	}


	DFBInputEvent	InputEvent;

	if ( /*( UIcontext.pEventBuffer == (IDirectFBEventBuffer *)0 )
	 || */( pKeyCode == (uint32_t *)0 ) 
	 || ( pIsReleased == (bool *)0 ) )
	{
		return	-1;
	}

	if ( UIcontext.pEventBuffer->GetEvent ( UIcontext.pEventBuffer, DFB_EVENT( &InputEvent ) ) != DFB_OK )
	{
		return	-2;
	}

#ifdef	UI_DRIVER_MESSAGE_KEY_EVENT_INFO
	UI_INFO("Input Event : Type = %d, Key ID = %d\n", InputEvent.type, InputEvent.key_id);

	UI_INFO("      clazz = %d  clazz of event\n", InputEvent.clazz);
	switch (InputEvent.clazz)
	{
	case	DFEC_NONE:
		UI_INFO("          none of these\n");
		break;
	case	DFEC_INPUT:
		UI_INFO("          raw input event\n");
		break;
	case	DFEC_WINDOW:
		UI_INFO("          windowing event\n");
		break;
	case	DFEC_USER:
		UI_INFO("          custom event for the user of this library\n");
		break;
	case	DFEC_UNIVERSAL:
		UI_INFO("          universal event for custom usage with variable size\n");
		break;
	case	DFEC_VIDEOPROVIDER:
		UI_INFO("          video provider event\n");
		break;
	case	DFEC_SURFACE:
		UI_INFO("          surface event\n");
		break;
	default:
		UI_INFO("          unknown\n");
		break;
	}

	UI_INFO("      type = %d  type of event\n", InputEvent.type);
	switch (InputEvent.type)
	{
	case	DIET_UNKNOWN:
		UI_INFO("          unknown event\n");
		break;
	case	DIET_KEYPRESS:
		UI_INFO("          a key is been pressed\n");
		break;
	case	DIET_KEYRELEASE:
		UI_INFO("          a key is been released\n");
		break;
	case	DIET_BUTTONPRESS:
		UI_INFO("          a (mouse) button is been pressed\n");
		break;
	case	DIET_BUTTONRELEASE:
		UI_INFO("          a (mouse) button is been released\n");
		break;
	case	DIET_AXISMOTION:
		UI_INFO("          mouse/joystick movement\n");
		break;
	default:
		UI_INFO("          unknown\n");
		break;
	}

	UI_INFO("      device_id = %d  source of event\n", InputEvent.device_id);

	UI_INFO("      flags = %d  which optional fields are valid\n", InputEvent.flags);
	if ( InputEvent.flags == DIEF_NONE)
	{
		UI_INFO("          no additional fields\n");
	}
	if ( (InputEvent.flags & DIEF_TIMESTAMP) == DIEF_TIMESTAMP)
	{
		UI_INFO("          timestamp is valid\n");
	}
	if ( (InputEvent.flags & DIEF_AXISABS) == DIEF_AXISABS)
	{
		UI_INFO("          axis and axisabs are valid\n");
	}
	if ( (InputEvent.flags & DIEF_AXISREL) == DIEF_AXISREL)
	{
		UI_INFO("          axis and axisrel are valid\n");
	}
	if ( (InputEvent.flags & DIEF_KEYCODE) == DIEF_KEYCODE)
	{
		UI_INFO("          DIEF_KEYCODE used internally by the input core, always set at application level\n");
	}
	if ( (InputEvent.flags & DIEF_KEYID) == DIEF_KEYID)
	{
		UI_INFO("          DIEF_KEYID used internally by the input core, always set at application level\n");
	}
	if ( (InputEvent.flags & DIEF_KEYSYMBOL) == DIEF_KEYSYMBOL)
	{
		UI_INFO("          DIEF_KEYSYMBOL used internally by the input core, always set at application level\n");
	}
	if ( (InputEvent.flags & DIEF_MODIFIERS) == DIEF_MODIFIERS)
	{
		UI_INFO("          DIEF_MODIFIERS used internally by the input core, always set at application level\n");
	}
	if ( (InputEvent.flags & DIEF_LOCKS) == DIEF_LOCKS)
	{
		UI_INFO("          DIEF_LOCKS used internally by the input core, always set at application level\n");
	}
	if ( (InputEvent.flags & DIEF_BUTTONS) == DIEF_BUTTONS)
	{
		UI_INFO("          DIEF_BUTTONS used internally by the input core, always set at application level\n");
	}
	if ( (InputEvent.flags & DIEF_GLOBAL) == DIEF_GLOBAL)
	{
		UI_INFO("          Only for event buffers creates by IDirectFB::CreateInputEventBuffer() with global events enabled\n");
		/* Indicates that the event would have been filtered if the buffer hadn't been global. */
	}
	if ( (InputEvent.flags & DIEF_REPEAT) == DIEF_REPEAT)
	{
		UI_INFO("          repeated event, e.g. key or button press\n");
	}
	if ( (InputEvent.flags & DIEF_FOLLOW) == DIEF_FOLLOW)
	{
		UI_INFO("          another event will follow immediately, e.g. x/y axis\n");
	}
	if ( (InputEvent.flags & DIEF_MIN) == DIEF_MIN)
	{
		UI_INFO("          minimum value is set, e.g. for absolute axis motion\n");
	}
	if ( (InputEvent.flags & DIEF_MAX) == DIEF_MAX)
	{
		UI_INFO("          maximum value is set, e.g. for absolute axis motion\n");
	}

	UI_INFO("   additionally (check flags)\n");
//	struct timeval                  timestamp;  /* time of event creation */
	UI_INFO("   DIET_KEYPRESS, DIET_KEYRELEASE\n");
	UI_INFO("      key_code = %d  hardware keycode, no mapping, -1 if device doesn't differentiate between several keys\n", InputEvent.key_code);
//	DFBInputDeviceKeyIdentifier     key_id;     /* basic mapping, modifier independent */
//	DFBInputDeviceKeySymbol         key_symbol; /* advanced mapping, unicode compatible, modifier dependent */
	UI_INFO("   additionally (check flags)\n");
	UI_INFO("      modifiers = 0x%X  pressed modifiers (optional)\n", InputEvent.modifiers);
#if	0
DIMM_SHIFT     = (1 << DIMKI_SHIFT),    /* Shift key is pressed */
DIMM_CONTROL   = (1 << DIMKI_CONTROL),  /* Control key is pressed */
DIMM_ALT       = (1 << DIMKI_ALT),      /* Alt key is pressed */
DIMM_ALTGR     = (1 << DIMKI_ALTGR),    /* AltGr key is pressed */
DIMM_META      = (1 << DIMKI_META),     /* Meta key is pressed */
DIMM_SUPER     = (1 << DIMKI_SUPER),    /* Super key is pressed */
DIMM_HYPER     = (1 << DIMKI_HYPER)     /* Hyper key is pressed */
#endif
//	DFBInputDeviceLockState         locks;      /* active locks (optional) */
	UI_INFO("   DIET_BUTTONPRESS, DIET_BUTTONRELEASE\n");
	UI_INFO("      button = %d  in case of a button event Left=0, Right=1, Middle=2\n", InputEvent.button);
	UI_INFO("      buttons = %d  mask of currently pressed buttons Left=1, Right=2, Middle=4\n", InputEvent.buttons);
	UI_INFO("   DIET_AXISMOTION\n");
	UI_INFO("      axis = %d  in case of an axis event X=0, Y=1, Z=2\n", InputEvent.axis);
	UI_INFO("   one of these two (check flags) : mouse/joystick\n");
	UI_INFO("      axisabs = %d  absolute mouse/joystick coordinate\n", InputEvent.axisabs);
	UI_INFO("      axisrel = %d  relative mouse/joystick movement\n", InputEvent.axisrel);
	UI_INFO("   general information\n");
	UI_INFO("      min = %d\n", InputEvent.min);
	UI_INFO("      max = %d\n", InputEvent.max);

#endif	/* UI_DRIVER_MESSAGE_KEY_EVENT_INFO */

	if ( (InputEvent.flags & DIEF_KEYCODE) == DIEF_KEYCODE )
	{
		if ( ( InputEvent.type == DIET_KEYPRESS ) || ( InputEvent.type == DIET_KEYRELEASE ) )
		{
			*pKeyCode = InputEvent.key_code;
			if ( InputEvent.type == DIET_KEYPRESS )
			{
				*pIsReleased = 0;
			}
			else /*if ( InputEvent.type == DIET_KEYRELEASE )*/
			{
				*pIsReleased = 1;
			}
			return	0;
		}
	}

	return	-3;
}


int		ui_printer_create_surface(void *pUI, uint32_t SurfaceWidth, uint32_t SurfaceHeight)
{
	DFBSurfaceDescription	SurfaceDescription;

	if ( ( pUI == (void *)0 ) || ( pUI != (void *)pUIcontext ) || ( SurfaceWidth == 0 ) || ( SurfaceHeight == 0 ) )
	{
		UI_ERROR( "Input parameter\n" );
		return	-1;
	}

	if ( UIcontext.MagicNumber != 0x1828128 )
	{
		UI_ERROR( "Not Initiailized UI\n" );
		return	-1;
	}

	if ( UIcontext.pPrinterSurface != (IDirectFBSurface *)0 )
	{
		UI_ERROR( "Arleady created printer surface\n" );
		return	-2;
	}

	UI_INFO( "Create Surface - Printer\n" );
	SurfaceDescription.flags = DSDESC_CAPS|DSDESC_PIXELFORMAT|DSDESC_WIDTH|DSDESC_HEIGHT;
	SurfaceDescription.caps = DSCAPS_FLIPPING;
	SurfaceDescription.pixelformat = DSPF_A8;
	SurfaceDescription.width = SurfaceWidth;
	SurfaceDescription.height = SurfaceHeight;
	if ( UIcontext.pDirectFb->CreateSurface( UIcontext.pDirectFb, &SurfaceDescription, &UIcontext.pPrinterSurface ) != DFB_OK )
	{
		UI_ERROR( "Error in CreateSurface()\n" );
		return	-2;
	}

	UIcontext.PrinterSurfaceWidth = SurfaceWidth;
	UIcontext.PrinterSurfaceHeight = SurfaceHeight;

	return	0;
}

int		ui_printer_font_set(void *pUI, char *pFontFile, int FontSize)
{
	IDirectFBFont *		pNewFont;
	DFBFontDescription	FontDescription;
	int					PrintedLineHeight;

	if ( ( pUI == (void *)0 ) || ( pUI != (void *)pUIcontext ) || ( pFontFile == (char *)0 ) )
	{
		return	-1;
	}

	if ( UIcontext.MagicNumber != 0x1828128 )
	{
		return	-1;
	}

	UI_INFO( "Create Font - Printer\n" );
	FontDescription.flags      = DFDESC_HEIGHT | DFDESC_ATTRIBUTES;
	FontDescription.height     = FontSize;
	FontDescription.attributes = DFFA_MONOCHROME;	//	DFFA_NONE
	if ( UIcontext.pDirectFb->CreateFont( UIcontext.pDirectFb, pFontFile, &FontDescription, &pNewFont ) != DFB_OK )
	{
		UI_ERROR( "Error in CreateFont()\n");
		return	-2;
	}
	if ( pNewFont->GetHeight( pNewFont, &PrintedLineHeight ) != DFB_OK )
	{
		UI_ERROR( "Get Font Height\n" );
		pNewFont->Release( pNewFont );
		return	-2;
	}
	PrintedLineHeight += 2;	/*Line Space*/
	UI_INFO( " Printer Line Height = %d\n", PrintedLineHeight );

	if ( UIcontext.pPrinterFont != (IDirectFBFont *)0 )
	{
		UI_INFO( " Need old printer font relase\n" );
		if ( UIcontext.pPrinterFont->Release( UIcontext.pPrinterFont ) != DFB_OK )
		{
			UI_ERROR( "Error in old printer font release\n" );
		}
		else
		{
			UI_INFO( " OK in old printer font relase\n" );
		}
	}

	UIcontext.pPrinterFont = pNewFont;
	UIcontext.pPrinterFontFile = pFontFile;
	UIcontext.PrinterFontSize = FontSize;
	UIcontext.PrintedLineHeight = PrintedLineHeight;

	return	0;
}

int		ui_printer_font_get_line_height(void *pUI, uint32_t *pLineHeight)
{
	IDirectFBFont *			pNewFont;
	IDirectFBSurface *		pNewSurface;
	DFBFontDescription		FontDescription;
	DFBSurfaceDescription	SurfaceDescription;
	int						PrintedImageHeight;

	if ( ( pUI == (void *)0 ) || ( pUI != (void *)pUIcontext ) || ( pLineHeight == (uint32_t *)0 ) )
	{
		return	-1;
	}

	if ( UIcontext.MagicNumber != 0x1828128 )
	{
		return	-1;
	}

	*pLineHeight = UIcontext.PrintedLineHeight;

	return	0;
}

void	ui_printer_mapping_surface_to_image_buffer(uint8_t *pSurface,
													uint8_t *pImageBuffer,
													uint32_t ByteSizeOfImageBufferWidth,
													uint32_t ByteSizeOfImageBufferHeight,
													uint32_t SurfaceWidth,
													bool LSBFirst,
													bool LRswitching)
{
	uint32_t	IndexForY;
	uint32_t	IndexForX;
	uint32_t	SurfaceLineIndex;
	uint32_t	SurfaceOffset;
	uint32_t	ImageLineIndex;
	uint32_t	ImageOffset;

	for ( IndexForY = 0; IndexForY < ByteSizeOfImageBufferHeight; IndexForY++ )
	{
		for ( IndexForX = 0; IndexForX < ( ByteSizeOfImageBufferWidth * 8 ); IndexForX++ )
		{
			SurfaceLineIndex = IndexForY * SurfaceWidth;
			/* 여기에서 좌우바뀜 수정 */
			if( LRswitching == true )
			{
				SurfaceOffset = ( ByteSizeOfImageBufferWidth * 8 ) - IndexForX - 1;
			}
			else
			{
				SurfaceOffset = IndexForX;
			}
			ImageLineIndex = IndexForY * ByteSizeOfImageBufferWidth;
			ImageOffset = IndexForX / 8;
			if ( pSurface[SurfaceLineIndex + SurfaceOffset] != 0 )
			{
				if ( LSBFirst == true )
				{
					pImageBuffer[ImageLineIndex + ImageOffset] |= (0x01 << (IndexForX & 0x00000007/* =IndexForX%8 */));
				}
				else
				{
					pImageBuffer[ImageLineIndex + ImageOffset] |= (0x80 >> (IndexForX & 0x00000007/* =IndexForX%8 */));
				}
			}
		}
	}
}

int		ui_printer_string(void *pUI,
						char *pString,
						UItextLayout_t UItextLayout,
						uint8_t *pImageBuffer,
						uint32_t ByteSizeOfImageBufferWidth,
						uint32_t ByteSizeOfImageBufferHeight)
{
	DFBResult		Result;
	int				PrintedWidth;
	int				PrintedHeight;
	UIposition_t	Position;
	uint32_t		PhysicalAddress;
	int				Pitch;
	void *			pVoid;

	if ( ( pUI == (void *)0 )
	 || ( pUI != (void *)pUIcontext )
	 || ( pString == (char *)0 )
	 || ( pImageBuffer == (uint8_t *)0 )
	 || ( ByteSizeOfImageBufferWidth == 0 )
	 || ( ByteSizeOfImageBufferHeight == 0 ) )
	{
		UI_ERROR( "Input Parameter\n" );
		return	-1;
	}

	if ( UIcontext.MagicNumber != 0x1828128 )
	{
		UI_ERROR( "Magic Number\n" );
		return	-1;
	}

	if ( ( ( ByteSizeOfImageBufferWidth * 8 ) > UIcontext.PrinterSurfaceWidth ) || ( ByteSizeOfImageBufferHeight > UIcontext.PrinterSurfaceHeight ) )
	{
		UI_ERROR( "Image Buffer Width(%d) > Surface W(%d) or Image Buffer Height(%d) > Surface H(%d)\n", ByteSizeOfImageBufferWidth, ( UIcontext.PrinterSurfaceWidth / 8 ), ByteSizeOfImageBufferHeight, UIcontext.PrinterSurfaceHeight );
		return	-1;
	}

	if ( UIcontext.pPrinterSurface->SetFont( UIcontext.pPrinterSurface, UIcontext.pPrinterFont ) != DFB_OK )
	{
		UI_ERROR( "Error in SetFont()\n" );
		return	-2;
	}
	UI_INFO( "OK in SetFont()\n" );

	UIcontext.pPrinterSurface->SetColor( UIcontext.pPrinterSurface, 0xFF, 0xFF, 0xFF, 0xFF );
	UIcontext.pPrinterSurface->Clear( UIcontext.pPrinterSurface, 0, 0, 0, 0 );

	if ( UIcontext.pPrinterFont->GetStringWidth( UIcontext.pPrinterFont, pString, -1/*bytes*/, &PrintedWidth ) != DFB_OK )
	{
		UI_ERROR( "Get String Width\n" );
		return	-3;
	}
	UI_INFO( "String Width = %d\n", PrintedWidth );

	if ( UIcontext.pPrinterFont->GetHeight( UIcontext.pPrinterFont, &PrintedHeight ) != DFB_OK )
	{
		UI_ERROR( "Get String Height\n" );
		return	-3;
	}
	UI_INFO( "String Height = %d\n", PrintedHeight );

	if ( ( PrintedWidth > UIcontext.PrinterSurfaceWidth ) || ( PrintedHeight > UIcontext.PrinterSurfaceHeight ) )
	{
		UI_ERROR( "PrintedWidth(%d) > Surface W(%d) or PrintedHeight(%d) > Surface H(%d)\n", PrintedWidth, UIcontext.PrinterSurfaceWidth, PrintedHeight, UIcontext.PrinterSurfaceHeight );
		return	-1;
	}

	if ( ( (PrintedWidth / 8) > ByteSizeOfImageBufferWidth ) || ( PrintedHeight > ByteSizeOfImageBufferHeight ) )
	{
		UI_ERROR( "PrintedWidth Byte(%d) > Image Buffer W(%d) or PrintedHeight Byte(%d) > Image Buffer H(%d)\n", (PrintedWidth / 8), UIcontext.PrinterSurfaceWidth, PrintedHeight, ByteSizeOfImageBufferHeight );
		return	-1;
	}

	Position = ui_make_text_draw_position( UItextLayout, 0, 0, ( ByteSizeOfImageBufferWidth * 8 ), ByteSizeOfImageBufferHeight, 0 );
	UI_INFO( "Position : X = %d, Y= %d\n", Position.X, Position.Y );
	if ( UIcontext.pPrinterSurface->DrawString( UIcontext.pPrinterSurface, pString, -1/*Bytes*/, Position.X, Position.Y, ui_make_text_flag( UItextLayout )/*Flasg*/ ) != DFB_OK )
	{
		UI_ERROR( "Draw\n" );
		return	-3;
	}
	UI_INFO( "Draw OK\n" );

	if ( UIcontext.pPrinterSurface->Flip( UIcontext.pPrinterSurface, NULL, 0 ) != DFB_OK )
	{
		UI_ERROR( "Flip\n" );
		return	-3;
	}
	UI_INFO( "Flip OK\n" );

	Result = UIcontext.pPrinterSurface->Lock( UIcontext.pPrinterSurface, DSLF_READ, &pVoid, &Pitch );
	if ( Result != DFB_OK )
	{
		UI_INFO( "Lock Fail\n" );
		DirectFBError ( "Lock Fail", Result );
	}
	else
	{
		UI_INFO( "Lock On : Address = 0x%08X, Pitch = %d\n", pVoid, Pitch );

		ui_printer_mapping_surface_to_image_buffer( (uint8_t *)pVoid,
													pImageBuffer,
													ByteSizeOfImageBufferWidth,
													ByteSizeOfImageBufferHeight,
													UIcontext.PrinterSurfaceWidth,
													false/*LSBFirst*/
													false/*LR switching*/);
	}

	if ( UIcontext.pPrinterSurface->Unlock( UIcontext.pPrinterSurface ) != DFB_OK )
	{
		UI_INFO( "Unlock Fail\n" );
	}

	usleep( 1000 );	/* Must be need for completed move data */

	return	( ByteSizeOfImageBufferWidth * ByteSizeOfImageBufferHeight );
}