Index: /titan/titan/cec.h
===================================================================
--- /titan/titan/cec.h	(revision 40412)
+++ /titan/titan/cec.h	(revision 40413)
@@ -3,4 +3,236 @@
 
 int cecon = 0;
+struct stimerthread* hdmiEventthread = NULL;
+
+
+void sendName(unsigned char address)
+{
+	unsigned char cmd = 0x47;
+	char data[16] = "TitanNit";
+	
+	data[8] = '\0';
+	sendMessage(address, cmd, data, strlen(data));
+
+}
+
+void sendMenuInfo(unsigned char address)
+{
+	unsigned char cmd = 0x8e;
+	char data[2];
+		
+	data[0] = 0x00;
+	if(status.standby > 0 || getconfigint("cec_menue", NULL) == 0)
+		data[0] = 0x01;
+	data[1] = '\0';
+	sendMessage(address, cmd, data, 1);
+}
+
+void sendVendorid(unsigned char address)
+{
+	unsigned char cmd = 0x87;
+	char data[4];
+	
+	data[0] = 0x00;
+	data[1] = 0x00;
+	data[2] = 0x00;
+	data[3] = '\0';
+	sendMessage(address, cmd, data, 3);
+}
+
+void sendSource(unsigned char address)
+{
+	unsigned char cmd = 0x82;
+	char data[4];
+	
+	data[0] = cec_physicalAddress[0];
+	data[1] = cec_physicalAddress[1];
+	data[2] = '\0';
+	sendMessage(address, cmd, data, 2);
+}
+
+void sendVersion(unsigned char address)
+{
+	unsigned char cmd = 0x9e;
+	char data[4];
+	
+	data[0] = 0x01;
+	data[1] = '\0';
+	sendMessage(address, cmd, data, 2);
+}
+
+void sendTVon()
+{
+	char data[3];
+	unsigned char address = 0x00;
+	unsigned char cmd = 0x04;
+	data[0] = '\0';
+	sendMessage(address, cmd, data, 0);
+}
+
+void sendswitch()
+{	
+	char data[3];
+	unsigned char address = 0x0f;
+	unsigned char cmd = 0x82;
+	data[0] = cec_physicalAddress[0];
+	data[1] = cec_physicalAddress[1];
+	data[2] = '\0';
+	sendMessage(address, cmd, data, 2);
+}
+
+int translateKey(unsigned char code)
+{
+	int key = 0;
+	switch (code)
+	{
+		case 0x32:
+			key = 0x8b;
+			break;
+		case 0x20:
+			key = 0x0b;
+			break;
+		case 0x21:
+			key = 0x02;
+			break;
+		case 0x22:
+			key = 0x03;
+			break;
+		case 0x23:
+			key = 0x04;
+			break;
+		case 0x24:
+			key = 0x05;
+			break;
+		case 0x25:
+			key = 0x06;
+			break;
+		case 0x26:
+			key = 0x07;
+			break;
+		case 0x27:
+			key = 0x08;
+			break;
+		case 0x28:
+			key = 0x09;
+			break;
+		case 0x29:
+			key = 0x0a;
+			break;
+		case 0x30:
+			key = 0x192;
+			break;
+		case 0x31:
+			key = 0x193;
+			break;
+		case 0x44:
+			key = 0xcf;
+			break;
+		case 0x45:
+			key = 0x80;
+			break;
+		case 0x46:
+			key = 0x77;
+			break;
+		case 0x47:
+			key = 0xa7;
+			break;
+		case 0x48:
+			key = 0xa8;
+			break;
+		case 0x49:
+			key = 0xd0;
+			break;
+		case 0x53:
+			key = 0x166;
+			break;
+		case 0x54:
+			key = 0x16a;
+			break;
+		case 0x60:
+			key = 0xcf;
+			break;
+		case 0x61:
+			key = 0xa4;
+			break;
+		case 0x62:
+			key = 0xa7;
+			break;
+		case 0x64:
+			key = 0x80;
+			break;
+		case 0x00:
+			key = 0x160;
+			break;
+		case 0x03:
+			key = 0x69;
+			break;
+		case 0x04:
+			key = 0x6a;
+			break;
+		case 0x01:
+			key = 0x67;
+			break;
+		case 0x02:
+			key = 0x6c;
+			break;
+		case 0x0d:
+			key = 0xae;
+			break;
+		case 0x72:
+			key = 0x18e;
+			break;
+		case 0x71:
+			key = 0x191;
+			break;
+		case 0x73:
+			key = 0x18f;
+			break;
+		case 0x74:
+			key = 0x190;
+			break;
+		default:
+			key = 0x8b;
+			break;
+	}
+	return key;
+}
+	
+void setVolumeForward()
+{
+	unsigned char address = 0x00;
+	unsigned char cmd = 0x7d;
+	char data[2];
+	data[0] = '\0';
+	
+	addconfiginttmp("ForwardVolume", 1);
+	data[0] = '\0';	
+	if(getconfigint("cec_volume", NULL) > 0)
+	{
+		if(getconfigint("cec_volume", NULL) == 1)
+			address = 0x05;
+		if(getconfigint("cec_volume", NULL) == 2)
+			address = 0x00;
+		
+		//cmd = 0x72;
+		//data[0] = 0x01;
+		//data[1] = '\0';
+		//m_lock(&status.cecmutex, 26);
+		//sendMessage(address, cmd, data, strlen(data));
+		//m_unlock(&status.cecmutex, 26);
+		
+		//cmd = 0x70;
+		//data[0] = 0x02;
+		//data[1] = 0x00;
+		//data[2] = '\0';
+		//m_lock(&status.cecmutex, 26);
+		//sendMessage(address, cmd, data, 2);
+		//m_unlock(&status.cecmutex, 26);
+		
+		cmd = 0x7d;
+		data[0] = '\0';
+		sendMessage(address, cmd, data, strlen(data));
+
+	}
+}
 
 void hdmiEvent()
@@ -8,9 +240,14 @@
 	fd_set rfds;
 	struct timeval tv;
-	struct cec_message rxmessage;
-	int ret = 0, len = 0;
-	
-	while(1)
-	{
+	struct cec_rx_message rxmessage;
+	int ret = 0;
+	int hasdata = 0;
+	int keypressed = 0;
+	int transkey = 0;
+	unsigned char pressedkey = 0x00;
+	
+	while (hdmiEventthread->aktion != STOP)
+	{
+		printf("**** start Thread\n");
 		tv.tv_sec = 0x7fffffff;
 		tv.tv_usec = 0;
@@ -18,6 +255,7 @@
 		FD_SET(status.hdmiFd, &rfds);
 
+		hasdata = 0;
+
 		ret = select(status.hdmiFd + 1, &rfds, NULL, NULL, &tv);
-			
 		if(ret > 0)
 		{
@@ -25,15 +263,110 @@
 			{
 #ifdef DREAMBOX
-				ret = ioctl(status.hdmiFd, 2, &rxmessage);
-				if(ret == 0)
-					len = rxmessage.length;
+				if (ioctl(status.hdmiFd, 2, &rxmessage) >= 0)
+					hasdata = 1;
+				
 				unsigned int val = 0;
-				ioctl(status.hdmiFd, 4, &val);	
+				ioctl(status.hdmiFd, 4, &val);
 #else
-				len = read(status.hdmiFd, &rxmessage, sizeof(struct cec_message));
+				if (read(status.hdmiFd, &rxmessage, 2) == 2)
+				{
+					if (read(status.hdmiFd, &rxmessage.data, rxmessage.length) == rxmessage.length)
+						hasdata = 1;
+				}
 #endif
-				if(len > 0)
+				if(hasdata)
 				{
-					printf("reveived adress: %02x datalen: %02x cmd: %02x\n", rxmessage.address, rxmessage.length, rxmessage.data[0]);
+					printf("CEC: rxmessage ->");
+					printf(" %02x ", rxmessage.address);
+					for (int i = 0; i < rxmessage.length; i++)
+						printf(" %02x", rxmessage.data[i]);
+					printf("\n");
+					
+					switch (rxmessage.data[0])
+					{
+						case 0x7e:
+						case 0x72: /* system audio mode status */
+						{
+							if(rxmessage.data[1] == 0x01)
+							{
+								addconfiginttmp("ForwardVolume", 1);
+								printf("HDMI_CEC: Volume forward is acticated\n");	
+							}
+							else
+							{
+								printf("HDMI_CEC: Volume forward is not supported\n");	
+								addconfiginttmp("ForwardVolume", 0);
+							}
+							break;
+						}
+						
+						case 0x46: /* request name */
+						{
+							sendName(rxmessage.address);
+							break;
+						}
+						case 0x8c: /* request vendor id */
+						{
+							sendVendorid(rxmessage.address);
+							break;
+						}
+						case 0x8d: /* menu request */
+						{
+							//if(rxmessage.data[1] == 0x02)
+								sendMenuInfo(rxmessage.address);
+							break;
+						}
+						case 0x82:
+						{
+						//cecon = 0;
+						//sendTVon();
+						sendswitch();
+						setFixedPhysicalAddress(getconfigint("cec_fixedAddress", NULL));
+						reportPhysicalAddress(0);
+						sendMenuInfo(0x00);
+						setVolumeForward();
+						}
+						case 0x00: /* feature abort */
+						{
+							if(rxmessage.data[1] == 0x44 || rxmessage.data[1] == 0x7d)
+							{
+								addconfiginttmp("ForwardVolume", 0);
+								printf("HdmiCec: volume forwarding not supported by device %02x\n", rxmessage.address);
+							}
+							break;
+						}
+						case 0x44: /* key pressed */
+						{
+							keypressed = 1;
+							pressedkey = rxmessage.data[1];
+							transkey = translateKey(pressedkey);
+							writerc(transkey);
+							break;
+						}
+						case 0x45: /* key released */
+						{
+							printf("HdmiCec: key received  -- %02x\n", pressedkey);
+							transkey = translateKey(pressedkey);
+							printf("HdmiCec: key TitanCode -- %i\n", transkey);
+							//writerc(transkey);
+							keypressed = 0;
+							break;
+						}
+						case 0x83: /* request address */
+						{
+							reportPhysicalAddress(1);
+							break;
+						}
+						case 0x85: /* request active source */
+						{
+							sendSource(rxmessage.address);
+							break;
+						}
+						case 0x9f: /* request cec version */
+						{
+							sendVersion(rxmessage.address);
+							break;
+						}
+					}
 				}
 			}
@@ -46,5 +379,7 @@
 			sleep(1);
 		}		
-	}	
+	}
+	hdmiEventthread = NULL;
+	printf("**** stop Thread\n");	
 }	
 
@@ -61,5 +396,5 @@
 	if (status.hdmiFd >= 0)
 	{
-		printf("eHdmiCEC: send message\n");
+		printf("HdmiCEC: send message\n");
 		printf("%02x ", message.address);
 		for(i = 0; i < message.length; i++)
@@ -81,4 +416,47 @@
 }
 
+void sendMessageReal_thread(struct stimerthread* timernode, struct cec_message* message, int flag)
+{
+	m_lock(&status.cecmutex, 26);
+	int i = 0;
+	if (status.hdmiFd >= 0)
+	{
+		printf("HdmiCEC: send message\n");
+		printf("%02x ", message->address);
+		for(i = 0; i < message->length; i++)
+		{
+			printf(" %02X", message->data[i]);
+		}
+		printf("\n");
+		int ret = 0;
+#ifdef DREAMBOX
+		message->flag = 1;
+		ret = ioctl(status.hdmiFd, 3, message);
+		if(ret == 0)
+			ret = 1 + message->length;
+#else
+		ret = write(status.hdmiFd, message, 2 + message->length);
+#endif
+		printf("%i Bytes wurden gesendet\n", ret);
+	}
+	free(message); message=NULL;
+	usleep(100000);
+	m_unlock(&status.cecmutex, 26);
+}
+
+void sendMessageReal_add(struct cec_message message)
+{
+	struct cec_message* smessage;
+	smessage = calloc(1, sizeof(struct cec_message));
+	if(smessage == NULL)
+	{
+		err("no mem");
+		return;
+	}
+	memcpy(smessage, &message, sizeof(struct cec_message));
+	addtimer(&sendMessageReal_thread, START, 1000, 1, (void*)smessage, NULL, NULL);
+}
+	
+
 void sendMessage(unsigned char address, unsigned char cmd, char *data, int length)
 {
@@ -89,8 +467,8 @@
 	message.data[0] = cmd;
 	memcpy(&message.data[1], data, length);
-	sendMessageReal(message);
-}
-
-void reportPhysicalAddress()
+	sendMessageReal_add(message);
+}
+
+void reportPhysicalAddress(int flag)
 {
 	struct cec_message txmessage;
@@ -101,6 +479,5 @@
 	txmessage.data[3] = cec_deviceType;
 	txmessage.length = 4;
-	sendMessageReal(txmessage);
-	sleep(1);
+	sendMessageReal_add(txmessage);
 }
 
@@ -163,14 +540,15 @@
 			cec_deviceType = addressinfo.type;
 			cec_logicalAddress = addressinfo.logical;
-			printf("eHdmiCEC: detected deviceType: %02X\n", addressinfo.type);
-			printf("eHdmiCEC: detected logical address: %02X\n", addressinfo.logical);
-			printf("eHdmiCEC: detected physical address: %02X%02X\n", addressinfo.physical[0], addressinfo.physical[1]);
+			printf("HdmiCEC: detected deviceType: %02X\n", addressinfo.type);
+			printf("HdmiCEC: detected logical address: %02X\n", addressinfo.logical);
+			printf("HdmiCEC: detected physical address: %02X%02X\n", addressinfo.physical[0], addressinfo.physical[1]);
 			if (status.cec_fixedAddress == 0)
 			{
+				//if(cecon > 0)
 				if (memcmp(cec_physicalAddress, addressinfo.physical, sizeof(cec_physicalAddress)))
 				{
-					printf("eHdmiCEC: detected physical address change: %02X%02X --> %02X%02X\n", cec_physicalAddress[0], cec_physicalAddress[1], addressinfo.physical[0], addressinfo.physical[1]);
+					printf("HdmiCEC: detected physical address change: %02X%02X --> %02X%02X\n", cec_physicalAddress[0], cec_physicalAddress[1], addressinfo.physical[0], addressinfo.physical[1]);
 					memcpy(cec_physicalAddress, addressinfo.physical, sizeof(cec_physicalAddress));
-					reportPhysicalAddress();
+					reportPhysicalAddress(0);
 					/* emit */ //addressChanged((cec_physicalAddress[0] << 8) | cec_physicalAddress[1]);
 				}
@@ -195,4 +573,6 @@
 	struct skin* tvswitch = getscreennode(cec, "tvswitch");
 	struct skin* cecfix = getscreennode(cec, "cecfix");
+	struct skin* volume = getscreennode(cec, "volume");
+	struct skin* menue = getscreennode(cec, "menue");
 	int rcret = 0;
 	int help = 0;	
@@ -240,4 +620,13 @@
 	else
 		setchoiceboxselection(cecfix, "1");
+	
+	addchoicebox(volume, "0", _("none"));
+	addchoicebox(volume, "1", _("Receiver"));
+	addchoicebox(volume, "2", _("TV"));
+	setchoiceboxselection(volume, getconfig("cec_volume", NULL));
+	
+	addchoicebox(menue, "0", _("off"));
+	addchoicebox(menue, "1", _("on"));
+	setchoiceboxselection(menue, getconfig("cec_menue", NULL));
 	
 	
@@ -253,4 +642,6 @@
 		tvswitch->hidden = YES;	
 		cecfix->hidden = YES;
+		volume->hidden = YES;
+		menue->hidden = YES;
 	}
 	else
@@ -265,4 +656,6 @@
 		tvswitch->hidden = NO;
 		cecfix->hidden = NO;	
+		volume->hidden = NO;
+		menue->hidden = NO;
 	}
 
@@ -289,4 +682,6 @@
 				tvswitch->hidden = YES;
 				cecfix->hidden = YES;	
+				volume->hidden = YES;
+				menue->hidden = YES;
 			}
 			else
@@ -301,4 +696,6 @@
 				tvswitch->hidden = NO;	
 				cecfix->hidden = NO;	
+				volume->hidden = NO;
+				menue->hidden = NO;
 			}
 		}
@@ -316,8 +713,10 @@
 			addconfig("cec_rec_on", recon->ret);
 			addconfig("cec_tv_switch", tvswitch->ret);
+			addconfig("cec_volume", volume->ret);
+			addconfig("cec_menue", menue->ret);
 			if(ostrcmp(cecfix->ret, "0") == 0)
 			{
 				addconfig("cec_fixedAddress", "0");
-				setFixedPhysicalAddress(0);
+				//setFixedPhysicalAddress(0);
 			}
 			else
@@ -326,6 +725,8 @@
 				help = (cec_physicalAddress[0] << 8) | cec_physicalAddress[1] ;
 				addconfigint("cec_fixedAddress", help);
-				setFixedPhysicalAddress(help);
+				//setFixedPhysicalAddress(help);
 			}
+			if(getconfigint("cec_activ", NULL) == 0 || getconfigint("cec_on", NULL) == 0)
+				cecinit();
 			break;
 		}
@@ -344,5 +745,5 @@
 		cec_physicalAddress[1] = address & 0xff;
 		/* report our (possibly new) address */
-		reportPhysicalAddress();
+		reportPhysicalAddress(0);
 	}
 	else
@@ -362,5 +763,15 @@
 	cec_logicalAddress = 1;
 	cec_deviceType = 1; /* default: recorder */
-
+	
+	if(getconfigint("cec_on", NULL) == 0)
+	{
+		addconfiginttmp("cec_activ", 0);
+		if(hdmiEventthread != NULL)
+			hdmiEventthread->aktion = STOP;	
+		return;
+	}
+	addconfiginttmp("cec_activ", 1);
+	
+	
 #ifdef DREAMBOX	
 	status.hdmiFd = open("/dev/misc/hdmi_cec0", O_RDWR | O_NONBLOCK);
@@ -372,5 +783,9 @@
 #endif
 	
-	setFixedPhysicalAddress(getconfigint("cec_fixedAddress", NULL));
+	if(hdmiEventthread == NULL)
+		hdmiEventthread = addtimer(&hdmiEvent, START, 10000, 1, NULL, NULL, NULL);
+		
+	getAddressInfo();
+	
 	if(checkbox("DM900") == 1 && getwaswakuptimer() != 1)
 	{	
@@ -381,5 +796,5 @@
 	return;
 }
-		
+
 void cecstandby()
 {
@@ -396,5 +811,4 @@
 			address = 0x0f;
 			sendMessage(address, cmd, data, strlen(data));
-			sleep(1);
 		}
 		if(getconfigint("cec_tv_off", NULL) == 1)
@@ -402,5 +816,5 @@
 			address = 0x00;
 			sendMessage(address, cmd, data, strlen(data));
-			sleep(1);
+			//sleep(1);
 		}
 		if(getconfigint("cec_rec_off", NULL) == 1)
@@ -408,5 +822,5 @@
 			address = 0x05;
 			sendMessage(address, cmd, data, strlen(data));
-			sleep(1);
+			//sleep(1);
 		}
 	}
@@ -427,5 +841,5 @@
 			address = 0x0f;
 			sendMessage(address, cmd, data, 0);
-			sleep(1);
+			//sleep(1);
 		}
 		if(getconfigint("cec_rec_on", NULL) == 1)
@@ -433,5 +847,5 @@
 			address = 0x05;
 			sendMessage(address, cmd, data, 0);
-			sleep(1);
+			//sleep(1);
 		}
 		if(getconfigint("cec_tv_on", NULL) == 1)
@@ -439,5 +853,5 @@
 			address = 0x00;
 			sendMessage(address, cmd, data, 0);
-			sleep(1);
+			//sleep(1);
 		}
 		if(getconfigint("cec_tv_switch", NULL) == 1)
@@ -449,9 +863,44 @@
 			data[2] = '\0';
 			sendMessage(address, cmd, data, 2);
-			sleep(1);
+			//sleep(1);
 		}
 		cecon = 1;
-	}
-}
-
+		printf("**********wakeup\n");	
+	}
+	if(cecon < 2)
+	{
+		//setFixedPhysicalAddress(getconfigint("cec_fixedAddress", NULL));
+		//setVolumeForward();
+		//sendMenuInfo(0x00);
+		cecon = 2;
+	}
+}
+
+void forwardKey(int key)
+{
+	char data[3];
+	unsigned char address = 0x00;
+	unsigned char cmd = 0x44;
+	
+	data[0] = '\0';
+	
+	if(getconfigint("cec_volume", NULL) == 1)
+			address = 0x05;
+	else if(getconfigint("cec_volume", NULL) == 2)
+			address = 0x00;
+	
+	if(key == getrcconfigint("rcvolup", NULL))
+		data[0] = 0x41;
+	else if(key == getrcconfigint("rcvoldown", NULL))
+		data[0] = 0x42;
+	else if(key == getrcconfigint("rcmute", NULL))
+		data[0] = 0x43;
+		
+	data[1] = '\0';
+	sendMessage(address, cmd, data, 1);
+	data[0] = '\0';
+	cmd = 0x45;
+	sendMessage(address, cmd, data, 0); /* release */
+}
+	
 #endif
Index: /titan/titan/mute.h
===================================================================
--- /titan/titan/mute.h	(revision 40412)
+++ /titan/titan/mute.h	(revision 40413)
@@ -11,4 +11,10 @@
 	struct skin* mute = getscreen("mute");
 
+	if(getconfigint("ForwardVolume", NULL) == 1)
+	{
+		forwardKey(getrcconfigint("rcmute", NULL));
+		return;
+	}
+	
 	if(getconfig("stepmute", NULL) == NULL)
 		addconfig("stepmute", "0");
