diff --git a/src/gui/cam_menu.cpp b/src/gui/cam_menu.cpp index 44b46b403..dabae28ab 100644 --- a/src/gui/cam_menu.cpp +++ b/src/gui/cam_menu.cpp @@ -57,6 +57,9 @@ void CCAMMenuHandler::init(void) { hintBox = NULL; ca = cCA::GetInstance(); + close_timer = 0; + in_menu = false; + menu_type = menu_slot = -1; } int CCAMMenuHandler::exec(CMenuTarget* parent, const std::string &actionkey) @@ -171,25 +174,23 @@ int CCAMMenuHandler::doMainMenu() cammenu->addItem( GenericMenuSeparatorLine ); i++; } - + in_menu = true; ret = cammenu->exec(NULL, ""); delete cammenu; + in_menu = false; return ret; } #define CI_MSG_TIME 5 -int CCAMMenuHandler::handleMsg (const neutrino_msg_t msg, neutrino_msg_data_t data) +int CCAMMenuHandler::handleMsg(const neutrino_msg_t msg, neutrino_msg_data_t data) { - int ret = messages_return::handled; //printf("CCAMMenuHandler::handleMsg: msg 0x%x data 0x%x\n", msg, data); - int camret = handleCamMsg(msg, data); - if(camret < 0) { - ret = messages_return::unhandled; - } - return ret; + int msgret; + handleCamMsg(msg, data, msgret); + return msgret; } -void CCAMMenuHandler::showHintBox (const neutrino_locale_t /*Caption*/, const char * const Text, uint32_t timeout) +void CCAMMenuHandler::showHintBox(const neutrino_locale_t /*Caption*/, const char * const Text, uint32_t timeout) { hideHintBox(); hintBox = new CHintBox(LOCALE_MESSAGEBOX_INFO, Text); @@ -209,9 +210,8 @@ void CCAMMenuHandler::hideHintBox(void) } } -int CCAMMenuHandler::handleCamMsg (const neutrino_msg_t msg, neutrino_msg_data_t data, bool from_menu) +int CCAMMenuHandler::handleCamMsg(const neutrino_msg_t msg, neutrino_msg_data_t data, int &msgret, bool from_menu) { - int ret = 0; char str[255]; char cnt[5]; int i; @@ -221,9 +221,19 @@ int CCAMMenuHandler::handleCamMsg (const neutrino_msg_t msg, neutrino_msg_data_t MMI_ENQUIRY_INFO *pMmiEnquiry = &MmiEnquiry; CA_MESSAGE Msg, *rMsg; - if (msg != NeutrinoMessages::EVT_CA_MESSAGE) - return from_menu ? 1 : -1; + printf("CCAMMenuHandler::handleCamMsg: msg %x data %x from %s\n", msg, data, from_menu ? "menu" : "neutrino"); + msgret = messages_return::unhandled; + if ((msg == NeutrinoMessages::EVT_TIMER) && (data == close_timer)) { + printf("CCAMMenuHandler::handleCamMsg: EVT_TIMER close_timer %d\n", close_timer); + g_RCInput->killTimer(close_timer); + msgret = messages_return::cancel_info; + } + + if (msg != NeutrinoMessages::EVT_CA_MESSAGE) + return 1; + + msgret = messages_return::handled; rMsg = (CA_MESSAGE *)data; if (!rMsg) @@ -236,34 +246,36 @@ int CCAMMenuHandler::handleCamMsg (const neutrino_msg_t msg, neutrino_msg_data_t CA_SLOT_TYPE SlotType = Msg.SlotType; int curslot = Msg.Slot; - printf("CCAMMenuHandler::handleCamMsg: msg %d from %s\n", MsgId, from_menu ? "menu" : "neutrino"); + printf("CCAMMenuHandler::handleCamMsg: CA msg %x from %s\n", MsgId, from_menu ? "menu" : "neutrino"); if (g_settings.ci_ignore_messages && !from_menu) return 1; + hideHintBox(); + if (SlotType != CA_SLOT_TYPE_SMARTCARD && SlotType != CA_SLOT_TYPE_CI) return -1; if(MsgId == CA_MESSAGE_MSG_INSERTED) { - hideHintBox(); snprintf(str, sizeof(str), "%s %d", g_Locale->getText(SlotType == CA_SLOT_TYPE_CI ? LOCALE_CI_INSERTED : LOCALE_SC_INSERTED), (int)curslot+1); printf("CCAMMenuHandler::handleCamMsg: %s\n", str); - ShowHint(LOCALE_MESSAGEBOX_INFO, str); + ShowHint(LOCALE_MESSAGEBOX_INFO, str, 450, 3); + if (in_menu) + msgret = messages_return::cancel_all; } else if (MsgId == CA_MESSAGE_MSG_REMOVED) { - hideHintBox(); - snprintf(str, sizeof(str), "%s %d", g_Locale->getText(SlotType == CA_SLOT_TYPE_CI ? LOCALE_CI_REMOVED : LOCALE_SC_REMOVED), (int)curslot+1); printf("CCAMMenuHandler::handleCamMsg: %s\n", str); - ShowHint(LOCALE_MESSAGEBOX_INFO, str); + ShowHint(LOCALE_MESSAGEBOX_INFO, str, 450, 3); +#if 0 + if (menu_slot == curslot && menu_type == SlotType) + return 3; +#endif + if (in_menu) + msgret = messages_return::cancel_all; } else if(MsgId == CA_MESSAGE_MSG_INIT_OK) { - if(hintBox != NULL) { - hintBox->hide(); - delete hintBox; - hintBox = NULL; - } char name[255] = "Unknown"; if (ca) ca->ModuleName(SlotType, curslot, name); @@ -272,10 +284,8 @@ int CCAMMenuHandler::handleCamMsg (const neutrino_msg_t msg, neutrino_msg_data_t g_Locale->getText(SlotType == CA_SLOT_TYPE_CI ? LOCALE_CI_INIT_OK : LOCALE_SC_INIT_OK), (int)curslot+1, name); printf("CCAMMenuHandler::handleCamMsg: %s\n", str); CCamManager::getInstance()->Start(CZapit::getInstance()->GetCurrentChannelID(), CCamManager::PLAY, true); - ShowHint(LOCALE_MESSAGEBOX_INFO, str); + ShowHint(LOCALE_MESSAGEBOX_INFO, str, 450, 3); } else if(MsgId == CA_MESSAGE_MSG_INIT_FAILED) { - hideHintBox(); - char name[255] = "Unknown"; if (ca) ca->ModuleName(SlotType, curslot, name); @@ -284,7 +294,7 @@ int CCAMMenuHandler::handleCamMsg (const neutrino_msg_t msg, neutrino_msg_data_t g_Locale->getText(SlotType == CA_SLOT_TYPE_CI ? LOCALE_CI_INIT_FAILED : LOCALE_SC_INIT_FAILED), (int)curslot+1, name); printf("CCAMMenuHandler::handleCamMsg: %s\n", str); - ShowHint(LOCALE_MESSAGEBOX_INFO, str); + ShowHint(LOCALE_MESSAGEBOX_INFO, str, 450, 3); } else if(MsgId == CA_MESSAGE_MSG_MMI_MENU || MsgId == CA_MESSAGE_MSG_MMI_LIST) { bool sublevel = false; @@ -299,8 +309,7 @@ int CCAMMenuHandler::handleCamMsg (const neutrino_msg_t msg, neutrino_msg_data_t printf("CCAMMenuHandler::handleCamMsg: slot %d menu ready, title %s choices %d\n", curslot, convertDVBUTF8(pMenu->title, strlen(pMenu->title), 0).c_str(), pMenu->choice_nb); - hideHintBox(); - + int menuret = menu_return::RETURN_REPAINT; int selected = -1; if(pMenu->choice_nb && from_menu) { CMenuWidget* menu = new CMenuWidget(convertDVBUTF8(pMenu->title, strlen(pMenu->title), 0).c_str(), NEUTRINO_ICON_SETTINGS); @@ -340,8 +349,7 @@ int CCAMMenuHandler::handleCamMsg (const neutrino_msg_t msg, neutrino_msg_data_t menu->addItem(new CMenuForwarder(convertDVBUTF8(pMenu->bottom, slen, 0).c_str(), false)); } - menu->exec(NULL, ""); - + menuret = menu->exec(NULL, ""); delete menu; delete selector; } else { @@ -349,8 +357,6 @@ int CCAMMenuHandler::handleCamMsg (const neutrino_msg_t msg, neutrino_msg_data_t char lstr[255]; int slen = 0; - hideHintBox(); -#if 1 if(strlen(pMenu->title)) slen += snprintf(&lstr[slen], 255-slen, "%s\n", pMenu->title); if(strlen(pMenu->subtitle)) @@ -358,22 +364,15 @@ int CCAMMenuHandler::handleCamMsg (const neutrino_msg_t msg, neutrino_msg_data_t if(strlen(pMenu->bottom)) slen += snprintf(&lstr[slen], 255-slen, "%s\n", pMenu->bottom); - for(i = 0; (i < pMenu->choice_nb) && (i < MAX_MMI_ITEMS); i++) { + for(i = 0; (i < pMenu->choice_nb) && (i < MAX_MMI_ITEMS); i++) slen += snprintf(&lstr[slen], 255-slen, "%s\n", pMenu->choice_item[i]); - } + ShowHint(LOCALE_MESSAGEBOX_INFO, convertDVBUTF8(lstr, slen, 0).c_str()); -#else - if(strlen(pMenu->subtitle)) - slen += snprintf(&lstr[slen], 255-slen, "\n%s", pMenu->subtitle); - if(strlen(pMenu->bottom)) - slen += snprintf(&lstr[slen], 255-slen, "\n%s", pMenu->bottom); - ShowHint(convertDVBUTF8(pMenu->title, strlen(pMenu->title), 0).c_str(), convertDVBUTF8(lstr, slen, 0).c_str()); -#endif return 0; } if(sublevel) - return 0; + return menuret == menu_return::RETURN_EXIT_ALL ? 3 : 0; if(selected >= 0) { printf("CCAMMenuHandler::handleCamMsg: selected %d:%s sublevel %s\n", selected, pMenu->choice_item[i], sublevel ? "yes" : "no"); @@ -381,7 +380,7 @@ int CCAMMenuHandler::handleCamMsg (const neutrino_msg_t msg, neutrino_msg_data_t timeoutEnd = CRCInput::calcTimeoutEnd(10); return 1; } else { - return 2; + return menuret == menu_return::RETURN_EXIT_ALL ? 3 : 2; } } else if(MsgId == CA_MESSAGE_MSG_MMI_REQ_INPUT) { @@ -391,7 +390,6 @@ int CCAMMenuHandler::handleCamMsg (const neutrino_msg_t msg, neutrino_msg_data_t memmove(pMmiEnquiry, (MMI_ENQUIRY_INFO *)Msg.Msg.Data[0], sizeof(MMI_ENQUIRY_INFO)); free((void *)Msg.Msg.Data[0]); printf("CCAMMenuHandler::handleCamMsg: slot %d input request, text %s\n", curslot, convertDVBUTF8(pMmiEnquiry->enquiryText, strlen(pMmiEnquiry->enquiryText), 0).c_str()); - hideHintBox(); std::string ENQAnswer; @@ -411,9 +409,15 @@ int CCAMMenuHandler::handleCamMsg (const neutrino_msg_t msg, neutrino_msg_data_t } } else if(MsgId == CA_MESSAGE_MSG_MMI_CLOSE) { - printf("CCAMMenuHandler::handleCamMsg: close request slot: %d\n", curslot); - hideHintBox(); - ca->MenuClose(SlotType, curslot); + int timeout = 0; + if (Msg.Flags & CA_MESSAGE_HAS_PARAM1_INT) + timeout = Msg.Msg.Param[0]; + printf("CCAMMenuHandler::handleCamMsg: close request slot: %d (timeout %d)\n", curslot, timeout); + //ca->MenuClose(SlotType, curslot); + if (timeout) + close_timer = g_RCInput->addTimer(timeout*1000*1000, true); + else + msgret = messages_return::cancel_info; return 0; } else if(MsgId == CA_MESSAGE_MSG_MMI_TEXT) { @@ -431,10 +435,8 @@ int CCAMMenuHandler::handleCamMsg (const neutrino_msg_t msg, neutrino_msg_data_t return -1; } CNeutrinoApp::getInstance()->zapTo(channel->getChannelID()); - } else - ret = -1; - //printf("CCAMMenuHandler::handleCamMsg: return %d\n", ret); - return ret; + } + return 1; } int CCAMMenuHandler::doMenu(int slot, CA_SLOT_TYPE slotType) @@ -444,6 +446,8 @@ int CCAMMenuHandler::doMenu(int slot, CA_SLOT_TYPE slotType) neutrino_msg_data_t data; bool doexit = false; + menu_slot = slot; + menu_type = slotType; while(!doexit) { printf("CCAMMenuHandler::doMenu: enter menu for slot %d\n", slot); @@ -460,20 +464,23 @@ int CCAMMenuHandler::doMenu(int slot, CA_SLOT_TYPE slotType) printf("CCAMMenuHandler::doMenu: menu timeout\n"); hideHintBox(); ShowHint(LOCALE_MESSAGEBOX_INFO, - g_Locale->getText(slotType == CA_SLOT_TYPE_CI ? LOCALE_CI_TIMEOUT : LOCALE_SC_TIMEOUT)); + g_Locale->getText(slotType == CA_SLOT_TYPE_CI ? LOCALE_CI_TIMEOUT : LOCALE_SC_TIMEOUT), 450, 3); ca->MenuClose(slotType, slot); return menu_return::RETURN_REPAINT; } - /* -1 = not our event, 0 = back to top menu, 1 = continue loop, 2 = quit */ - int ret = handleCamMsg(msg, data, true); - printf("CCAMMenuHandler::doMenu: handleCamMsg %d\n", ret); - if(ret < 0 && (msg > CRCInput::RC_Messages)) { - if ( CNeutrinoApp::getInstance()->handleMsg( msg, data ) & ( messages_return::cancel_all | messages_return::cancel_info ) ) + /* -1 = not our event, 0 = back to top menu, 1 = continue loop, 2 = quit , 3 = quit all*/ + int msgret; + int ret = handleCamMsg(msg, data, msgret, true); + printf("CCAMMenuHandler::doMenu: handleCamMsg ret: %d\n", ret); + if((msgret & messages_return::unhandled) && (msg > CRCInput::RC_Events)) { + if (CNeutrinoApp::getInstance()->handleMsg(msg, data) & (messages_return::cancel_all | messages_return::cancel_info)) { doexit = true; res = menu_return::RETURN_EXIT_ALL; + break; } - } else if (ret == 1) { + } + if (ret == 1) { /* workaround: dont cycle here on timers */ if (msg != NeutrinoMessages::EVT_TIMER) timeoutEnd = CRCInput::calcTimeoutEnd(10); @@ -481,6 +488,10 @@ int CCAMMenuHandler::doMenu(int slot, CA_SLOT_TYPE slotType) } else if (ret == 2) { doexit = true; break; + } else if (ret == 3) { + res = menu_return::RETURN_EXIT_ALL; + doexit = true; + break; } else { // ret == 0 break; } @@ -488,6 +499,7 @@ int CCAMMenuHandler::doMenu(int slot, CA_SLOT_TYPE slotType) } ca->MenuClose(slotType, slot); hideHintBox(); + menu_type = menu_slot = -1; printf("CCAMMenuHandler::doMenu: return\n"); return res; } diff --git a/src/gui/cam_menu.h b/src/gui/cam_menu.h index 4a8c1fa43..829aa3433 100644 --- a/src/gui/cam_menu.h +++ b/src/gui/cam_menu.h @@ -37,10 +37,13 @@ class CCAMMenuHandler : public CMenuTarget, public CChangeObserver CHintBox * hintBox; cCA *ca; uint64_t timeoutEnd; - //int slot; + uint32_t close_timer; + int menu_slot; + int menu_type; + bool in_menu; int doMenu(int slot, CA_SLOT_TYPE slotType); int doMainMenu(); - int handleCamMsg (const neutrino_msg_t msg, neutrino_msg_data_t data, bool from_menu = false); + int handleCamMsg (const neutrino_msg_t msg, neutrino_msg_data_t data, int &msgret, bool from_menu = false); void hideHintBox(void); void showHintBox(const neutrino_locale_t Caption, const char * const Text, uint32_t timeout = 0); public: