static int menu_select_internal(SDL_Surface *screen, menu_t *p_menu, int *p_submenus, int sel, void (*select_next_cb)(menu_t *p, void *data), void *select_next_cb_data, int font_size) { int ret = -1; int i; for (i = 0; i < p_menu->n_submenus; i++) p_menu->p_submenus[i].sel = p_submenus[i]; while(1) { uint32_t keys; int sel_last = p_menu->cur_sel; menu_draw(screen, p_menu, 0, font_size); SDL_Flip(screen); keys = menu_wait_key_press(); quit_thread = 1; if (keys & KEY_UP) {select_next(p_menu, 0, -1, 1);play_click(0);} else if (keys & KEY_DOWN) {select_next(p_menu, 0, 1, 1);play_click(0);} else if (keys & KEY_PAGEUP) {select_next(p_menu, 0, -20, 0);play_click(0);} else if (keys & KEY_PAGEDOWN) {select_next(p_menu, 0, 20, 0);play_click(0);} else if (keys & KEY_LEFT) {select_next(p_menu, -1, 0 ,1);play_click(0);} else if (keys & KEY_RIGHT) {select_next(p_menu, 1, 0 ,1);play_click(0);} else if (keys & KEY_ESCAPE) {play_click(2);break;} else if (keys & KEY_SELECT) { ret = p_menu->cur_sel; int i; for (i=0; i<p_menu->n_submenus; i++) p_submenus[i] = p_menu->p_submenus[i].sel; play_click(1); break; } /* Invoke the callback when an entry is selected */ if (sel_last != p_menu->cur_sel && select_next_cb != NULL) select_next_cb(p_menu, select_next_cb_data); } SDL_FillRect(screen, 0, SDL_MapRGB(screen->format, 0, 0, 0)); return ret; }
void CRCInput::getMsg_us(neutrino_msg_t * msg, neutrino_msg_data_t * data, unsigned long long Timeout, bool bAllowRepeatLR) { static unsigned long long last_keypress = 0ULL; unsigned long long getKeyBegin; //static __u16 rc_last_key = KEY_MAX; static __u16 rc_last_repeat_key = KEY_MAX; struct timeval tv, tvselect; unsigned long long InitialTimeout = Timeout; long long targetTimeout; int timer_id; fd_set rfds; t_input_event ev; *data = 0; // wiederholung reinmachen - dass wirklich die ganze zeit bis timeout gewartet wird! gettimeofday( &tv, NULL ); getKeyBegin = (unsigned long long) tv.tv_usec + (unsigned long long)((unsigned long long) tv.tv_sec * (unsigned long long) 1000000); while(1) { timer_id = 0; if ( timers.size()> 0 ) { gettimeofday( &tv, NULL ); unsigned long long t_n= (unsigned long long) tv.tv_usec + (unsigned long long)((unsigned long long) tv.tv_sec * (unsigned long long) 1000000); if ( timers[0].times_out< t_n ) { timer_id = checkTimers(); *msg = NeutrinoMessages::EVT_TIMER; *data = timer_id; return; } else { targetTimeout = timers[0].times_out - t_n; if ( (unsigned long long) targetTimeout> Timeout) targetTimeout= Timeout; else timer_id = timers[0].id; } } else targetTimeout= Timeout; tvselect.tv_sec = targetTimeout/1000000; tvselect.tv_usec = targetTimeout%1000000; FD_ZERO(&rfds); for (int i = 0; i < NUMBER_OF_EVENT_DEVICES; i++) { if (fd_rc[i] != -1) FD_SET(fd_rc[i], &rfds); } #ifdef KEYBOARD_INSTEAD_OF_REMOTE_CONTROL if (true) #else if (fd_keyb> 0) #endif /* KEYBOARD_INSTEAD_OF_REMOTE_CONTROL */ FD_SET(fd_keyb, &rfds); FD_SET(fd_event, &rfds); FD_SET(fd_pipe_high_priority[0], &rfds); FD_SET(fd_pipe_low_priority[0], &rfds); int status = select(fd_max+1, &rfds, NULL, NULL, &tvselect); if ( status == -1 ) { perror("[neutrino - getMsg_us]: select returned "); // in case of an error return timeout...?! *msg = RC_timeout; *data = 0; return; } else if ( status == 0 ) // Timeout! { if ( timer_id != 0 ) { timer_id = checkTimers(); if ( timer_id != 0 ) { *msg = NeutrinoMessages::EVT_TIMER; *data = timer_id; return; } else continue; } else { *msg = RC_timeout; *data = 0; return; } } if(FD_ISSET(fd_pipe_high_priority[0], &rfds)) { struct event buf; read(fd_pipe_high_priority[0], &buf, sizeof(buf)); *msg = buf.msg; *data = buf.data; // printf("got event from high-pri pipe %x %x\n", *msg, *data ); return; } #ifdef KEYBOARD_INSTEAD_OF_REMOTE_CONTROL if (FD_ISSET(fd_keyb, &rfds)) { int trkey; char key = 0; read(fd_keyb, &key, sizeof(key)); switch(key) { case 27: // <- Esc trkey = KEY_HOME; break; case 10: // <- Return case 'o': trkey = KEY_OK; break; case 'p': trkey = KEY_POWER; break; case 's': trkey = KEY_SETUP; break; case 'h': trkey = KEY_HELP; break; case 'i': trkey = KEY_UP; break; case 'm': trkey = KEY_DOWN; break; case 'j': trkey = KEY_LEFT; break; case 'k': trkey = KEY_RIGHT; break; case 'r': trkey = KEY_RED; break; case 'g': trkey = KEY_GREEN; break; case 'y': trkey = KEY_YELLOW; break; case 'b': trkey = KEY_BLUE; break; case '0': trkey = RC_0; break; case '1': trkey = RC_1; break; case '2': trkey = RC_2; break; case '3': trkey = RC_3; break; case '4': trkey = RC_4; break; case '5': trkey = RC_5; break; case '6': trkey = RC_6; break; case '7': trkey = RC_7; break; case '8': trkey = RC_8; break; case '9': trkey = RC_9; break; case '+': trkey = RC_plus; break; case '-': trkey = RC_minus; break; case 'a': trkey = KEY_A; break; case 'u': trkey = KEY_U; break; case '/': trkey = KEY_SLASH; break; case '\\': trkey = KEY_BACKSLASH; break; default: trkey = RC_nokey; } if (trkey != RC_nokey) { *msg = trkey; *data = 0; /* <- button pressed */ return; } } #else /* if(FD_ISSET(fd_keyb, &rfds)) { char key = 0; read(fd_keyb, &key, sizeof(key)); printf("keyboard: %d\n", rc_key); } */ #endif /* KEYBOARD_INSTEAD_OF_REMOTE_CONTROL */ if(FD_ISSET(fd_event, &rfds)) { //printf("[neutrino] event - accept!\n"); socklen_t clilen; struct sockaddr_in cliaddr; clilen = sizeof(cliaddr); int fd_eventclient = accept(fd_event, (struct sockaddr *) &cliaddr, &clilen); *msg = RC_nokey; //printf("[neutrino] network event - read!\n"); CEventServer::eventHead emsg; int read_bytes= recv(fd_eventclient, &emsg, sizeof(emsg), MSG_WAITALL); //printf("[neutrino] event read %d bytes - following %d bytes\n", read_bytes, emsg.dataSize ); if ( read_bytes == sizeof(emsg) ) { bool dont_delete_p = false; unsigned char* p; p= new unsigned char[ emsg.dataSize + 1 ]; if ( p!=NULL ) { read_bytes= recv(fd_eventclient, p, emsg.dataSize, MSG_WAITALL); //printf("[neutrino] eventbody read %d bytes - initiator %x\n", read_bytes, emsg.initiatorID ); if ( emsg.initiatorID == CEventServer::INITID_CONTROLD ) { switch(emsg.eventID) { case CControldClient::EVT_VOLUMECHANGED : *msg = NeutrinoMessages::EVT_VOLCHANGED; *data = 0; break; case CControldClient::EVT_MUTECHANGED : *msg = NeutrinoMessages::EVT_MUTECHANGED; *data = (unsigned) p; dont_delete_p = true; break; case CControldClient::EVT_VCRCHANGED : *msg = NeutrinoMessages::EVT_VCRCHANGED; *data = *(int*) p; break; case CControldClient::EVT_MODECHANGED : *msg = NeutrinoMessages::EVT_MODECHANGED; *data = *(int*) p; break; default: printf("[neutrino] event INITID_CONTROLD - unknown eventID 0x%x\n", emsg.eventID ); } } else if ( emsg.initiatorID == CEventServer::INITID_HTTPD ) { switch(emsg.eventID) { case NeutrinoMessages::SHUTDOWN : *msg = NeutrinoMessages::SHUTDOWN; *data = 0; break; case NeutrinoMessages::EVT_POPUP : *msg = NeutrinoMessages::EVT_POPUP; *data = (unsigned) p; dont_delete_p = true; break; case NeutrinoMessages::EVT_EXTMSG : *msg = NeutrinoMessages::EVT_EXTMSG; *data = (unsigned) p; dont_delete_p = true; break; case NeutrinoMessages::CHANGEMODE : // Change *msg = NeutrinoMessages::CHANGEMODE; *data = *(unsigned*) p; break; case NeutrinoMessages::STANDBY_TOGGLE : *msg = NeutrinoMessages::STANDBY_TOGGLE; *data = 0; break; case NeutrinoMessages::STANDBY_ON : *msg = NeutrinoMessages::STANDBY_ON; *data = 0; break; case NeutrinoMessages::STANDBY_OFF : *msg = NeutrinoMessages::STANDBY_OFF; *data = 0; break; case NeutrinoMessages::EVT_START_PLUGIN : *msg = NeutrinoMessages::EVT_START_PLUGIN; *data = (unsigned) p; dont_delete_p = true; break; case NeutrinoMessages::LOCK_RC : *msg = NeutrinoMessages::LOCK_RC; *data = 0; break; case NeutrinoMessages::UNLOCK_RC : *msg = NeutrinoMessages::UNLOCK_RC; *data = 0; break; default: printf("[neutrino] event INITID_HTTPD - unknown eventID 0x%x\n", emsg.eventID ); } } else if ( emsg.initiatorID == CEventServer::INITID_SECTIONSD ) { //printf("[neutrino] event - from SECTIONSD %x %x\n", emsg.eventID, *(unsigned*) p); switch(emsg.eventID) { case CSectionsdClient::EVT_TIMESET: { struct timeval tv; gettimeofday( &tv, NULL ); long long timeOld = (long long) tv.tv_usec + (long long)((long long) tv.tv_sec * (long long) 1000000); //printf("[neutrino] event TIMESET from SECTIONSD %x %x\n", emsg.eventID, *(unsigned*) p); //g_Sectionsd->registerEvent(CSectionsdClient::EVT_TIMESET, 222, NEUTRINO_UDS_NAME); stime((time_t*) p); gettimeofday( &tv, NULL ); long long timeNew = (long long) tv.tv_usec + (long long)((long long) tv.tv_sec * (long long) 1000000); delete[] p;//new [] delete [] p= new unsigned char[ sizeof(long long) ]; *(long long*) p = timeNew - timeOld; if ((long long)last_keypress > *(long long*)p) last_keypress += *(long long *)p; // Timer anpassen for(std::vector<timer>::iterator e = timers.begin(); e != timers.end(); ++e) if (e->correct_time) e->times_out+= *(long long*) p; *msg = NeutrinoMessages::EVT_TIMESET; *data = (neutrino_msg_data_t) p; dont_delete_p = true; } break; case CSectionsdClient::EVT_GOT_CN_EPG: printf("[neutrino] CSectionsdClient::EVT_GOT_CN_EPG\n"); *msg = NeutrinoMessages::EVT_CURRENTNEXT_EPG; *data = (neutrino_msg_data_t) p; dont_delete_p = true; break; case CSectionsdClient::EVT_SERVICES_UPDATE: *msg = NeutrinoMessages::EVT_SERVICES_UPD; *data = 0; break; case CSectionsdClient::EVT_BOUQUETS_UPDATE: break; case CSectionsdClient::EVT_WRITE_SI_FINISHED: *msg = NeutrinoMessages::EVT_SI_FINISHED; *data = 0; break; default: printf("[neutrino] event INITID_SECTIONSD - unknown eventID 0x%x\n", emsg.eventID ); } } else if ( emsg.initiatorID == CEventServer::INITID_ZAPIT ) { //printf("[neutrino] event - from ZAPIT %x %x\n", emsg.eventID, *(unsigned*) p); switch(emsg.eventID) { case CZapitClient::EVT_RECORDMODE_ACTIVATED: *msg = NeutrinoMessages::EVT_RECORDMODE; *data = true; break; case CZapitClient::EVT_RECORDMODE_DEACTIVATED: *msg = NeutrinoMessages::EVT_RECORDMODE; *data = false; break; case CZapitClient::EVT_ZAP_COMPLETE: *msg = NeutrinoMessages::EVT_ZAP_COMPLETE; break; case CZapitClient::EVT_ZAP_FAILED: *msg = NeutrinoMessages::EVT_ZAP_FAILED; break; case CZapitClient::EVT_ZAP_SUB_FAILED: *msg = NeutrinoMessages::EVT_ZAP_SUB_FAILED; break; case CZapitClient::EVT_ZAP_COMPLETE_IS_NVOD: *msg = NeutrinoMessages::EVT_ZAP_ISNVOD; break; case CZapitClient::EVT_ZAP_SUB_COMPLETE: *msg = NeutrinoMessages::EVT_ZAP_SUB_COMPLETE; break; case CZapitClient::EVT_SCAN_COMPLETE: *msg = NeutrinoMessages::EVT_SCAN_COMPLETE; *data = 0; break; case CZapitClient::EVT_SCAN_NUM_TRANSPONDERS: *msg = NeutrinoMessages::EVT_SCAN_NUM_TRANSPONDERS; *data = *(unsigned*) p; break; case CZapitClient::EVT_SCAN_REPORT_NUM_SCANNED_TRANSPONDERS: *msg = NeutrinoMessages::EVT_SCAN_REPORT_NUM_SCANNED_TRANSPONDERS; *data = *(unsigned*) p; break; case CZapitClient::EVT_SCAN_REPORT_FREQUENCY: *msg = NeutrinoMessages::EVT_SCAN_REPORT_FREQUENCY; *data = *(unsigned*) p; break; case CZapitClient::EVT_SCAN_FOUND_A_CHAN: *msg = NeutrinoMessages::EVT_SCAN_FOUND_A_CHAN; break; case CZapitClient::EVT_SCAN_SERVICENAME: *msg = NeutrinoMessages::EVT_SCAN_SERVICENAME; break; case CZapitClient::EVT_SCAN_FOUND_TV_CHAN: *msg = NeutrinoMessages::EVT_SCAN_FOUND_TV_CHAN; *data = *(unsigned*) p; break; case CZapitClient::EVT_SCAN_FOUND_RADIO_CHAN: *msg = NeutrinoMessages::EVT_SCAN_FOUND_RADIO_CHAN; *data = *(unsigned*) p; break; case CZapitClient::EVT_SCAN_FOUND_DATA_CHAN: *msg = NeutrinoMessages::EVT_SCAN_FOUND_DATA_CHAN; *data = *(unsigned*) p; break; case CZapitClient::EVT_SCAN_REPORT_FREQUENCYP: *msg = NeutrinoMessages::EVT_SCAN_REPORT_FREQUENCYP; *data = *(unsigned*) p; break; case CZapitClient::EVT_SCAN_NUM_CHANNELS: *msg = NeutrinoMessages::EVT_SCAN_NUM_CHANNELS; *data = *(unsigned*) p; break; case CZapitClient::EVT_SCAN_PROVIDER: *msg = NeutrinoMessages::EVT_SCAN_PROVIDER; break; case CZapitClient::EVT_SCAN_SATELLITE: *msg = NeutrinoMessages::EVT_SCAN_SATELLITE; break; case CZapitClient::EVT_BOUQUETS_CHANGED: *msg = NeutrinoMessages::EVT_BOUQUETSCHANGED; *data = 0; break; case CZapitClient::EVT_SERVICES_CHANGED: *msg = NeutrinoMessages::EVT_SERVICESCHANGED; *data = 0; break; case CZapitClient::EVT_ZAP_CA_CLEAR: *msg = NeutrinoMessages::EVT_ZAP_CA_CLEAR; *data = *(unsigned*) p; break; case CZapitClient::EVT_ZAP_CA_LOCK: *msg = NeutrinoMessages::EVT_ZAP_CA_LOCK; *data = *(unsigned*) p; break; case CZapitClient::EVT_ZAP_CA_FTA: *msg = NeutrinoMessages::EVT_ZAP_CA_FTA; *data = *(unsigned*) p; break; case CZapitClient::EVT_ZAP_CA_ID : *msg = NeutrinoMessages::EVT_ZAP_CA_ID; *data = *(unsigned*) p; break; case CZapitClient::EVT_SCAN_FAILED: *msg = NeutrinoMessages::EVT_SCAN_FAILED; *data = 0; break; case CZapitClient::EVT_ZAP_MOTOR: *msg = NeutrinoMessages::EVT_ZAP_MOTOR; *data = *(unsigned*) p; break; case CZapitClient::EVT_SDT_CHANGED: *msg = NeutrinoMessages::EVT_SERVICES_UPD; *data = 0; break; default: printf("[neutrino] event INITID_ZAPIT - unknown eventID 0x%x\n", emsg.eventID ); } if (((*msg) >= CRCInput::RC_WithData) && ((*msg) < CRCInput::RC_WithData + 0x10000000)) { *data = (neutrino_msg_data_t) p; dont_delete_p = true; } } else if ( emsg.initiatorID == CEventServer::INITID_TIMERD ) { /* if (emsg.eventID==CTimerdClient::EVT_ANNOUNCE_NEXTPROGRAM) { } if (emsg.eventID==CTimerdClient::EVT_NEXTPROGRAM) { *msg = NeutrinoMessages::EVT_NEXTPROGRAM; *data = (neutrino_msg_data_t) p; dont_delete_p = true; } */ switch(emsg.eventID) { case CTimerdClient::EVT_ANNOUNCE_RECORD : *msg = NeutrinoMessages::ANNOUNCE_RECORD; *data = (unsigned) p; dont_delete_p = true; break; case CTimerdClient::EVT_ANNOUNCE_ZAPTO : *msg = NeutrinoMessages::ANNOUNCE_ZAPTO; *data = 0; break; case CTimerdClient::EVT_ANNOUNCE_SHUTDOWN : *msg = NeutrinoMessages::ANNOUNCE_SHUTDOWN; *data = 0; break; case CTimerdClient::EVT_ANNOUNCE_SLEEPTIMER : *msg = NeutrinoMessages::ANNOUNCE_SLEEPTIMER; *data = 0; break; case CTimerdClient::EVT_SLEEPTIMER : *msg = NeutrinoMessages::SLEEPTIMER; *data = 0; break; case CTimerdClient::EVT_RECORD_START : *msg = NeutrinoMessages::RECORD_START; *data = (unsigned) p; dont_delete_p = true; break; case CTimerdClient::EVT_RECORD_STOP : *msg = NeutrinoMessages::RECORD_STOP; *data = (unsigned) p; dont_delete_p = true; break; case CTimerdClient::EVT_ZAPTO : *msg = NeutrinoMessages::ZAPTO; *data = (unsigned) p; dont_delete_p = true; break; case CTimerdClient::EVT_SHUTDOWN : *msg = NeutrinoMessages::SHUTDOWN; *data = 0; break; case CTimerdClient::EVT_STANDBY_ON : *msg = NeutrinoMessages::STANDBY_ON; *data = 0; break; case CTimerdClient::EVT_STANDBY_OFF : *msg = NeutrinoMessages::STANDBY_OFF; *data = 0; break; case CTimerdClient::EVT_REMIND : *msg = NeutrinoMessages::REMIND; *data = (unsigned) p; dont_delete_p = true; break; case CTimerdClient::EVT_EXEC_PLUGIN : *msg = NeutrinoMessages::EVT_START_PLUGIN; *data = (unsigned) p; dont_delete_p = true; break; case CTimerdClient::EVT_BATCHEPG : *msg = NeutrinoMessages::EVT_BATCHEPG; *data = 0; break; default : printf("[neutrino] event INITID_TIMERD - unknown eventID 0x%x\n", emsg.eventID ); } } else if (emsg.initiatorID == CEventServer::INITID_NEUTRINO) { if ((emsg.eventID == NeutrinoMessages::EVT_RECORDING_ENDED) && (read_bytes == sizeof(stream2file_status2_t))) { *msg = NeutrinoMessages::EVT_RECORDING_ENDED; *data = (neutrino_msg_data_t) p; dont_delete_p = true; } } else if (emsg.initiatorID == CEventServer::INITID_GENERIC_INPUT_EVENT_PROVIDER) { if (read_bytes == sizeof(int)) { *msg = *(int *)p; *data = emsg.eventID; } } else printf("[neutrino] event - unknown initiatorID 0x%x\n", emsg.initiatorID); if ( !dont_delete_p ) { delete[] p;//new [] delete [] p= NULL; } } } else { printf("[neutrino] event - read failed!\n"); } ::close(fd_eventclient); if ( *msg != RC_nokey ) { // raus hier :) //printf("[neutrino] event 0x%x\n", *msg); return; } } for (int i = 0; i < NUMBER_OF_EVENT_DEVICES; i++) { if ((fd_rc[i] != -1) && (FD_ISSET(fd_rc[i], &rfds))) { int ret; ret = read(fd_rc[i], &ev, sizeof(t_input_event)); if(ret != sizeof(t_input_event)) continue; printf("key: %04x value %d, translate: %04x -%s-\n", ev.code, ev.value, translate(ev.code, i), getKeyName(translate(ev.code, i)).c_str()); uint32_t trkey = translate(ev.code, i); if (trkey == RC_nokey) continue; if (ev.value) { #ifdef RCDEBUG printf("got keydown native key: %04x %04x, translate: %04x -%s-\n", ev.code, ev.code&0x1f, translate(ev.code, 0), getKeyName(translate(ev.code, 0)).c_str()); printf("rc_last_key %04x rc_last_repeat_key %04x\n\n", rc_last_key, rc_last_repeat_key); #endif if (firstKey) { firstKey = false; int wtw = ::open ("/proc/stb/fp/was_timer_wakeup", O_WRONLY); if (wtw > -1) { write(wtw, "0\n", 2); ::close(wtw); } } unsigned long long now_pressed; bool keyok = true; tv = ev.time; now_pressed = (unsigned long long) tv.tv_usec + (unsigned long long)((unsigned long long) tv.tv_sec * (unsigned long long) 1000000); if (ev.code == rc_last_key) { /* only allow selected keys to be repeated */ /* (why?) */ if(mayRepeat(trkey) || (trkey == RC_up) || (trkey == RC_down ) || (trkey == RC_plus ) || (trkey == RC_minus ) || (trkey == RC_page_down ) || (trkey == RC_page_up ) || //(trkey == RC_standby) || ((bAllowRepeatLR) && ((trkey == RC_left ) || (trkey == RC_right)))) { #ifdef ENABLE_REPEAT_CHECK if (rc_last_repeat_key != ev.code) { if ((now_pressed > last_keypress + repeat_block) || /* accept all keys after time discontinuity: */ (now_pressed < last_keypress)) rc_last_repeat_key = ev.code; else keyok = false; } #endif } else keyok = false; } else rc_last_repeat_key = KEY_MAX; rc_last_key = ev.code; if (keyok) { #ifdef ENABLE_REPEAT_CHECK if ((now_pressed > last_keypress + repeat_block_generic) || /* accept all keys after time discontinuity: */ (now_pressed < last_keypress)) #endif { last_keypress = now_pressed; *msg = trkey; *data = 0; /* <- button pressed */ if(g_settings.key_click) play_click(); return; } } /*if keyok */ } /* if (ev.value) */ else { // clear rc_last_key on keyup event #ifdef RCDEBUG printf("got keyup native key: %04x %04x, translate: %04x -%s-\n", ev.code, ev.code&0x1f, translate(ev.code, 0), getKeyName(translate(ev.code, 0)).c_str() ); #endif rc_last_key = KEY_MAX; if (trkey == RC_standby) { *msg = RC_standby; *data = 1; /* <- button released */ return; } } }/* if FDSET */ } /* for NUMBER_OF_EVENT_DEVICES */ if(FD_ISSET(fd_pipe_low_priority[0], &rfds)) { struct event buf; read(fd_pipe_low_priority[0], &buf, sizeof(buf)); *msg = buf.msg; *data = buf.data; // printf("got event from low-pri pipe %x %x\n", *msg, *data ); return; } if ( InitialTimeout == 0 ) { //nicht warten wenn kein key da ist *msg = RC_timeout; *data = 0; return; } else { //timeout neu kalkulieren gettimeofday( &tv, NULL ); long long getKeyNow = (long long) tv.tv_usec + (long long)((long long) tv.tv_sec * (long long) 1000000); long long diff = (getKeyNow - getKeyBegin); if( Timeout <= (unsigned long long) diff ) { *msg = RC_timeout; *data = 0; return; } else Timeout -= diff; } } }
void CRCInput::getMsg_us(neutrino_msg_t * msg, neutrino_msg_data_t * data, uint64_t Timeout, bool bAllowRepeatLR) { static uint64_t last_keypress = 0ULL; //uint64_t getKeyBegin; //static __u16 rc_last_key = KEY_MAX; static __u16 rc_last_repeat_key = KEY_MAX; struct timeval tv; struct timeval tvselect; uint64_t InitialTimeout = Timeout; int64_t targetTimeout; int timer_id; fd_set rfds; *data = 0; /* reopen a missing input device * TODO: real hot-plugging, e.g. of keyboards and triggering this loop... * right now it is only run if some event is happening "by accident" */ if (!input_stopped) { for (int i = 0; i < NUMBER_OF_EVENT_DEVICES; i++) { if (fd_rc[i] == -1) open(i); } } // wiederholung reinmachen - dass wirklich die ganze zeit bis timeout gewartet wird! uint64_t getKeyBegin = time_monotonic_us(); while(1) { /* we later check for ev.type = EV_SYN which is 0x00, so set something invalid here... */ timer_id = 0; if ( !timers.empty() ) { uint64_t t_n = time_monotonic_us(); if ( timers[0].times_out< t_n ) { timer_id = checkTimers(); *msg = NeutrinoMessages::EVT_TIMER; *data = timer_id; return; } else { targetTimeout = timers[0].times_out - t_n; if ( (uint64_t) targetTimeout> Timeout) targetTimeout= Timeout; else timer_id = timers[0].id; } } else targetTimeout= Timeout; tvselect.tv_sec = targetTimeout/1000000; tvselect.tv_usec = targetTimeout%1000000; FD_ZERO(&rfds); for (int i = 0; i < NUMBER_OF_EVENT_DEVICES; i++) { if (fd_rc[i] != -1) FD_SET(fd_rc[i], &rfds); } #ifdef KEYBOARD_INSTEAD_OF_REMOTE_CONTROL if (true) #else if (fd_keyb> 0) #endif /* KEYBOARD_INSTEAD_OF_REMOTE_CONTROL */ FD_SET(fd_keyb, &rfds); FD_SET(fd_event, &rfds); FD_SET(fd_pipe_high_priority[0], &rfds); FD_SET(fd_pipe_low_priority[0], &rfds); int status = select(fd_max+1, &rfds, NULL, NULL, &tvselect); if ( status == -1 ) { perror("[neutrino - getMsg_us]: select returned "); // in case of an error return timeout...?! *msg = RC_timeout; *data = 0; return; } else if ( status == 0 ) // Timeout! { if ( timer_id != 0 ) { timer_id = checkTimers(); if ( timer_id != 0 ) { *msg = NeutrinoMessages::EVT_TIMER; *data = timer_id; return; } else continue; } else { *msg = RC_timeout; *data = 0; return; } } if(FD_ISSET(fd_pipe_high_priority[0], &rfds)) { struct event buf; read(fd_pipe_high_priority[0], &buf, sizeof(buf)); *msg = buf.msg; *data = buf.data; // printf("got event from high-pri pipe %x %x\n", *msg, *data ); return; } #ifdef KEYBOARD_INSTEAD_OF_REMOTE_CONTROL if (FD_ISSET(fd_keyb, &rfds)) { uint32_t trkey; char key = 0; read(fd_keyb, &key, sizeof(key)); switch(key) { case 27: // <- Esc trkey = KEY_HOME; break; case 10: // <- Return case 'o': trkey = KEY_OK; break; case 'p': trkey = KEY_POWER; break; case 's': trkey = KEY_SETUP; break; case 'h': trkey = KEY_HELP; break; case 'i': trkey = KEY_UP; break; case 'm': trkey = KEY_DOWN; break; case 'j': trkey = KEY_LEFT; break; case 'k': trkey = KEY_RIGHT; break; case 'r': trkey = KEY_RED; break; case 'g': trkey = KEY_GREEN; break; case 'y': trkey = KEY_YELLOW; break; case 'b': trkey = KEY_BLUE; break; case '0': trkey = RC_0; break; case '1': trkey = RC_1; break; case '2': trkey = RC_2; break; case '3': trkey = RC_3; break; case '4': trkey = RC_4; break; case '5': trkey = RC_5; break; case '6': trkey = RC_6; break; case '7': trkey = RC_7; break; case '8': trkey = RC_8; break; case '9': trkey = RC_9; break; case '+': trkey = RC_plus; break; case '-': trkey = RC_minus; break; case 'a': trkey = KEY_A; break; case 'u': trkey = KEY_U; break; case '/': trkey = KEY_SLASH; break; case '\\': trkey = KEY_BACKSLASH; break; default: trkey = RC_nokey; } if (trkey != RC_nokey) { *msg = trkey; *data = 0; /* <- button pressed */ return; } } #else /* if(FD_ISSET(fd_keyb, &rfds)) { char key = 0; read(fd_keyb, &key, sizeof(key)); printf("keyboard: %d\n", rc_key); } */ #endif /* KEYBOARD_INSTEAD_OF_REMOTE_CONTROL */ if(FD_ISSET(fd_event, &rfds)) { //printf("[neutrino] event - accept!\n"); socklen_t clilen; struct sockaddr_in cliaddr; clilen = sizeof(cliaddr); int fd_eventclient = accept(fd_event, (struct sockaddr *) &cliaddr, &clilen); *msg = RC_nokey; //printf("[neutrino] network event - read!\n"); CEventServer::eventHead emsg; int read_bytes= recv(fd_eventclient, &emsg, sizeof(emsg), MSG_WAITALL); //printf("[neutrino] event read %d bytes - following %d bytes\n", read_bytes, emsg.dataSize ); if ( read_bytes == sizeof(emsg) ) { bool dont_delete_p = false; unsigned char* p; p= new unsigned char[ emsg.dataSize + 1 ]; if ( p!=NULL ) { read_bytes= recv(fd_eventclient, p, emsg.dataSize, MSG_WAITALL); //printf("[neutrino] eventbody read %d bytes - initiator %x\n", read_bytes, emsg.initiatorID ); #if 0 if ( emsg.initiatorID == CEventServer::INITID_CONTROLD ) { switch(emsg.eventID) { case CControldClient::EVT_VOLUMECHANGED : *msg = NeutrinoMessages::EVT_VOLCHANGED; *data = 0; break; case CControldClient::EVT_MUTECHANGED : *msg = NeutrinoMessages::EVT_MUTECHANGED; *data = (unsigned) p; dont_delete_p = true; break; case CControldClient::EVT_VCRCHANGED : *msg = NeutrinoMessages::EVT_VCRCHANGED; *data = *(int*) p; break; case CControldClient::EVT_MODECHANGED : *msg = NeutrinoMessages::EVT_MODECHANGED; *data = *(int*) p; break; default: printf("[neutrino] event INITID_CONTROLD - unknown eventID 0x%x\n", emsg.eventID ); } } else #endif if ( emsg.initiatorID == CEventServer::INITID_HTTPD ) { switch(emsg.eventID) { case NeutrinoMessages::SHUTDOWN : *msg = NeutrinoMessages::SHUTDOWN; *data = 0; break; case NeutrinoMessages::REBOOT : *msg = NeutrinoMessages::REBOOT; *data = 0; break; case NeutrinoMessages::EVT_POPUP : *msg = NeutrinoMessages::EVT_POPUP; *data = (unsigned long) p; dont_delete_p = true; break; case NeutrinoMessages::EVT_EXTMSG : *msg = NeutrinoMessages::EVT_EXTMSG; *data = (unsigned long) p; dont_delete_p = true; break; case NeutrinoMessages::CHANGEMODE : // Change *msg = NeutrinoMessages::CHANGEMODE; *data = *(unsigned long*) p; break; case NeutrinoMessages::STANDBY_TOGGLE : *msg = NeutrinoMessages::STANDBY_TOGGLE; *data = 0; break; case NeutrinoMessages::STANDBY_ON : *msg = NeutrinoMessages::STANDBY_ON; *data = 0; break; case NeutrinoMessages::STANDBY_OFF : *msg = NeutrinoMessages::STANDBY_OFF; *data = 0; break; case NeutrinoMessages::EVT_START_PLUGIN : *msg = NeutrinoMessages::EVT_START_PLUGIN; *data = (unsigned long) p; dont_delete_p = true; break; case NeutrinoMessages::LOCK_RC : *msg = NeutrinoMessages::LOCK_RC; *data = 0; break; case NeutrinoMessages::UNLOCK_RC : *msg = NeutrinoMessages::UNLOCK_RC; *data = 0; break; case NeutrinoMessages::RELOAD_SETUP : *msg = NeutrinoMessages::RELOAD_SETUP; *data = 0; break; case NeutrinoMessages::EVT_HDMI_CEC_VIEW_ON: *msg = NeutrinoMessages::EVT_HDMI_CEC_VIEW_ON; *data = 0; break; case NeutrinoMessages::EVT_HDMI_CEC_STANDBY: *msg = NeutrinoMessages::EVT_HDMI_CEC_STANDBY; *data = 0; break; case NeutrinoMessages::EVT_SET_MUTE : *msg = NeutrinoMessages::EVT_SET_MUTE; *data = *(char*) p; break; case NeutrinoMessages::EVT_SET_VOLUME : *msg = NeutrinoMessages::EVT_SET_VOLUME; *data = *(char*) p; break; case NeutrinoMessages::RECORD_START : *msg = NeutrinoMessages::RECORD_START; *data = (unsigned long) p; dont_delete_p = true; break; case NeutrinoMessages::RECORD_STOP : *msg = NeutrinoMessages::RECORD_STOP; *data = (unsigned long) p; dont_delete_p = true; break; default: printf("[neutrino] event INITID_HTTPD - unknown eventID 0x%x\n", emsg.eventID ); } } else if ( emsg.initiatorID == CEventServer::INITID_SECTIONSD ) { //printf("[neutrino] event - from SECTIONSD %x %x\n", emsg.eventID, *(unsigned*) p); switch(emsg.eventID) { case CSectionsdClient::EVT_TIMESET: { printf("[neutrino] CSectionsdClient::EVT_TIMESET: timediff %" PRId64 "\n", *(int64_t*) p); /* compensate last_keypress for autorepeat / long press detection * I doubt this works correcty, if we had kernel 3.4+, using * EVIOCSCLOCKID ioctl would be better. * Still guessing the logic behind the condition... */ if ((int64_t)last_keypress > *(int64_t*)p) last_keypress += *(int64_t *)p; *msg = NeutrinoMessages::EVT_TIMESET; *data = (neutrino_msg_data_t) p; dont_delete_p = true; break; } case CSectionsdClient::EVT_GOT_CN_EPG: printf("[neutrino] CSectionsdClient::EVT_GOT_CN_EPG\n"); *msg = NeutrinoMessages::EVT_CURRENTNEXT_EPG; *data = (neutrino_msg_data_t) p; dont_delete_p = true; break; case CSectionsdClient::EVT_WRITE_SI_FINISHED: *msg = NeutrinoMessages::EVT_SI_FINISHED; *data = 0; break; case CSectionsdClient::EVT_EIT_COMPLETE: printf("[neutrino] CSectionsdClient::EVT_EIT_COMPLETE\n"); *msg = NeutrinoMessages::EVT_EIT_COMPLETE; *data = (neutrino_msg_data_t) p; dont_delete_p = true; break; #if 0 case CSectionsdClient::EVT_SERVICES_UPDATE: *msg = NeutrinoMessages::EVT_SERVICES_UPD; *data = 0; break; case CSectionsdClient::EVT_BOUQUETS_UPDATE: break; #endif default: printf("[neutrino] event INITID_SECTIONSD - unknown eventID 0x%x\n", emsg.eventID ); } } else if ( emsg.initiatorID == CEventServer::INITID_ZAPIT ) { //printf("[neutrino] event - from ZAPIT %x %x\n", emsg.eventID, *(unsigned*) p); switch(emsg.eventID) { case CZapitClient::EVT_RECORDMODE_ACTIVATED: *msg = NeutrinoMessages::EVT_RECORDMODE; *data = true; break; case CZapitClient::EVT_RECORDMODE_DEACTIVATED: *msg = NeutrinoMessages::EVT_RECORDMODE; *data = false; break; case CZapitClient::EVT_ZAP_COMPLETE: *msg = NeutrinoMessages::EVT_ZAP_COMPLETE; break; case CZapitClient::EVT_ZAP_FAILED: *msg = NeutrinoMessages::EVT_ZAP_FAILED; break; case CZapitClient::EVT_ZAP_SUB_FAILED: *msg = NeutrinoMessages::EVT_ZAP_SUB_FAILED; break; case CZapitClient::EVT_ZAP_COMPLETE_IS_NVOD: *msg = NeutrinoMessages::EVT_ZAP_ISNVOD; break; case CZapitClient::EVT_ZAP_SUB_COMPLETE: *msg = NeutrinoMessages::EVT_ZAP_SUB_COMPLETE; break; case CZapitClient::EVT_SCAN_COMPLETE: *msg = NeutrinoMessages::EVT_SCAN_COMPLETE; *data = 0; break; case CZapitClient::EVT_SCAN_NUM_TRANSPONDERS: *msg = NeutrinoMessages::EVT_SCAN_NUM_TRANSPONDERS; *data = *(unsigned*) p; break; case CZapitClient::EVT_SCAN_REPORT_NUM_SCANNED_TRANSPONDERS: *msg = NeutrinoMessages::EVT_SCAN_REPORT_NUM_SCANNED_TRANSPONDERS; *data = *(unsigned*) p; break; case CZapitClient::EVT_SCAN_FOUND_A_CHAN: *msg = NeutrinoMessages::EVT_SCAN_FOUND_A_CHAN; break; case CZapitClient::EVT_SCAN_SERVICENAME: *msg = NeutrinoMessages::EVT_SCAN_SERVICENAME; break; case CZapitClient::EVT_SCAN_FOUND_TV_CHAN: *msg = NeutrinoMessages::EVT_SCAN_FOUND_TV_CHAN; *data = *(unsigned*) p; break; case CZapitClient::EVT_SCAN_FOUND_RADIO_CHAN: *msg = NeutrinoMessages::EVT_SCAN_FOUND_RADIO_CHAN; *data = *(unsigned*) p; break; case CZapitClient::EVT_SCAN_FOUND_DATA_CHAN: *msg = NeutrinoMessages::EVT_SCAN_FOUND_DATA_CHAN; *data = *(unsigned*) p; break; case CZapitClient::EVT_SCAN_REPORT_FREQUENCYP: *msg = NeutrinoMessages::EVT_SCAN_REPORT_FREQUENCYP; *data = *(unsigned*) p; break; case CZapitClient::EVT_SCAN_NUM_CHANNELS: *msg = NeutrinoMessages::EVT_SCAN_NUM_CHANNELS; *data = *(unsigned*) p; break; case CZapitClient::EVT_SCAN_PROVIDER: *msg = NeutrinoMessages::EVT_SCAN_PROVIDER; break; case CZapitClient::EVT_SCAN_SATELLITE: *msg = NeutrinoMessages::EVT_SCAN_SATELLITE; break; case CZapitClient::EVT_BOUQUETS_CHANGED: *msg = NeutrinoMessages::EVT_BOUQUETSCHANGED; *data = 0; break; case CZapitClient::EVT_SERVICES_CHANGED: *msg = NeutrinoMessages::EVT_SERVICESCHANGED; *data = 0; break; case CZapitClient::EVT_ZAP_CA_CLEAR: *msg = NeutrinoMessages::EVT_ZAP_CA_CLEAR; *data = *(unsigned*) p; break; case CZapitClient::EVT_ZAP_CA_LOCK: *msg = NeutrinoMessages::EVT_ZAP_CA_LOCK; *data = *(unsigned*) p; break; case CZapitClient::EVT_ZAP_CA_FTA: *msg = NeutrinoMessages::EVT_ZAP_CA_FTA; *data = *(unsigned*) p; break; case CZapitClient::EVT_ZAP_CA_ID : *msg = NeutrinoMessages::EVT_ZAP_CA_ID; *data = *(unsigned*) p; break; case CZapitClient::EVT_SCAN_FAILED: *msg = NeutrinoMessages::EVT_SCAN_FAILED; *data = 0; break; case CZapitClient::EVT_ZAP_MOTOR: *msg = NeutrinoMessages::EVT_ZAP_MOTOR; *data = *(unsigned*) p; break; case CZapitClient::EVT_SDT_CHANGED: *msg = NeutrinoMessages::EVT_SERVICES_UPD; *data = 0; break; case CZapitClient::EVT_PMT_CHANGED: *msg = NeutrinoMessages::EVT_PMT_CHANGED; *data = (neutrino_msg_data_t) p; break; case CZapitClient::EVT_TUNE_COMPLETE: *msg = NeutrinoMessages::EVT_TUNE_COMPLETE; *data = (neutrino_msg_data_t) p; break; case CZapitClient::EVT_BACK_ZAP_COMPLETE: *msg = NeutrinoMessages::EVT_BACK_ZAP_COMPLETE; *data = (neutrino_msg_data_t) p; break; case CZapitClient::EVT_WEBTV_ZAP_COMPLETE: *msg = NeutrinoMessages::EVT_WEBTV_ZAP_COMPLETE; *data = (neutrino_msg_data_t) p; break; default: printf("[neutrino] event INITID_ZAPIT - unknown eventID 0x%x\n", emsg.eventID ); } if (((*msg) >= CRCInput::RC_WithData) && ((*msg) < CRCInput::RC_WithData + 0x10000000)) { *data = (neutrino_msg_data_t) p; dont_delete_p = true; } } else if ( emsg.initiatorID == CEventServer::INITID_TIMERD ) { /* if (emsg.eventID==CTimerdClient::EVT_ANNOUNCE_NEXTPROGRAM) { } if (emsg.eventID==CTimerdClient::EVT_NEXTPROGRAM) { *msg = NeutrinoMessages::EVT_NEXTPROGRAM; *data = (neutrino_msg_data_t) p; dont_delete_p = true; } */ switch(emsg.eventID) { case CTimerdClient::EVT_ANNOUNCE_RECORD : *msg = NeutrinoMessages::ANNOUNCE_RECORD; *data = (unsigned long) p; dont_delete_p = true; break; case CTimerdClient::EVT_ANNOUNCE_ZAPTO : *msg = NeutrinoMessages::ANNOUNCE_ZAPTO; *data = (neutrino_msg_data_t)p; dont_delete_p = true; break; case CTimerdClient::EVT_ANNOUNCE_SHUTDOWN : *msg = NeutrinoMessages::ANNOUNCE_SHUTDOWN; *data = 0; break; case CTimerdClient::EVT_ANNOUNCE_SLEEPTIMER : *msg = NeutrinoMessages::ANNOUNCE_SLEEPTIMER; *data = 0; break; case CTimerdClient::EVT_SLEEPTIMER : *msg = NeutrinoMessages::SLEEPTIMER; *data = 0; break; case CTimerdClient::EVT_RECORD_START : *msg = NeutrinoMessages::RECORD_START; *data = (unsigned long) p; dont_delete_p = true; break; case CTimerdClient::EVT_RECORD_STOP : *msg = NeutrinoMessages::RECORD_STOP; *data = (unsigned long) p; dont_delete_p = true; break; case CTimerdClient::EVT_ZAPTO : *msg = NeutrinoMessages::ZAPTO; *data = (unsigned long) p; dont_delete_p = true; break; case CTimerdClient::EVT_SHUTDOWN : *msg = NeutrinoMessages::SHUTDOWN; *data = 0; break; case CTimerdClient::EVT_STANDBY_ON : *msg = NeutrinoMessages::STANDBY_ON; *data = 0; break; case CTimerdClient::EVT_STANDBY_OFF : *msg = NeutrinoMessages::STANDBY_OFF; *data = 0; break; case CTimerdClient::EVT_REMIND : *msg = NeutrinoMessages::REMIND; *data = (unsigned long) p; dont_delete_p = true; break; case CTimerdClient::EVT_EXEC_PLUGIN : *msg = NeutrinoMessages::EVT_START_PLUGIN; *data = (unsigned long) p; dont_delete_p = true; break; default : printf("[neutrino] event INITID_TIMERD - unknown eventID 0x%x\n", emsg.eventID ); } } else if (emsg.initiatorID == CEventServer::INITID_NEUTRINO) { printf("CRCInput::getMsg_us: INITID_NEUTRINO: msg %x size %d data %p\n", (int) emsg.eventID, emsg.dataSize, p); if (emsg.eventID == NeutrinoMessages::EVT_HOTPLUG) { printf("EVT_HOTPLUG: [%s]\n", (char *) p); *msg = emsg.eventID; *data = (neutrino_msg_data_t) p; dont_delete_p = true; } #if 0 if ((emsg.eventID == NeutrinoMessages::EVT_RECORDING_ENDED) && (read_bytes == sizeof(stream2file_status2_t))) { *msg = NeutrinoMessages::EVT_RECORDING_ENDED; *data = (neutrino_msg_data_t) p; dont_delete_p = true; } #endif } else if (emsg.initiatorID == CEventServer::INITID_GENERIC_INPUT_EVENT_PROVIDER) { if (read_bytes == sizeof(int)) { *msg = *(int *)p; *data = emsg.eventID; } } else printf("[neutrino] event - unknown initiatorID 0x%x\n", emsg.initiatorID); switch (emsg.eventID) { case NeutrinoMessages::EVT_CURRENTEPG: case NeutrinoMessages::EVT_NEXTEPG: { CSectionsdClient::CurrentNextInfo *cn = (CSectionsdClient::CurrentNextInfo *) p; delete [] cn; p = NULL; break; } default: if (!dont_delete_p) { delete[] p; p = NULL; } } } } else { printf("[neutrino] event - read failed!\n"); } ::close(fd_eventclient); if ( *msg != RC_nokey ) { // raus hier :) //printf("[neutrino] event 0x%x\n", *msg); return; } } for (int i = 0; i < NUMBER_OF_EVENT_DEVICES; i++) { if ((fd_rc[i] != -1) && (FD_ISSET(fd_rc[i], &rfds))) { t_input_event ev; int ret = read(fd_rc[i], &ev, sizeof(t_input_event)); if (ret != sizeof(t_input_event)) { if (errno == ENODEV) { /* hot-unplugged? */ ::close(fd_rc[i]); fd_rc[i] = -1; } continue; } if (ev.type == EV_SYN) continue; /* ignore... */ SHTDCNT::getInstance()->resetSleepTimer(); if (ev.value && firstKey) { firstKey = false; CTimerManager::getInstance()->cancelShutdownOnWakeup(); } uint32_t trkey = translate(ev.code); #ifdef _DEBUG printf("%d key: %04x value %d, translate: %04x -%s-\n", ev.value, ev.code, ev.value, trkey, getKeyName(trkey).c_str()); #endif if (trkey == RC_nokey) continue; if (g_settings.longkeypress_duration > LONGKEYPRESS_OFF) { uint64_t longPressNow = time_monotonic_us(); if (ev.value == 0 && longPressEnd) { if (longPressNow < longPressEnd) { // Key was a potential long press, but wasn't pressed long enough longPressEnd = 0; ev.value = 1; } else { // Long-press, key released after time limit longPressEnd = 0; continue; } } else if (ev.value == 1 && mayLongPress(trkey, bAllowRepeatLR)) { // A long-press may start here. longPressEnd = longPressNow + 1000 * g_settings.longkeypress_duration; rc_last_key = KEY_MAX; continue; } else if (ev.value == 2 && longPressEnd) { if (longPressEnd < longPressNow) { // Key was pressed long enough. ev.value = 1; trkey |= RC_Repeat; } else { // Long-press, but key still not released. Skip. continue; } } } if (ev.value) { #ifdef RCDEBUG printf("rc_last_key %04x rc_last_repeat_key %04x\n\n", rc_last_key, rc_last_repeat_key); #endif if (*timer_wakeup) { unlink("/tmp/.timer_wakeup"); *timer_wakeup = false; #if HAVE_SPARK_HARDWARE || HAVE_DUCKBOX_HARDWARE CCECSetup cecsetup; cecsetup.setCECSettings(true); #endif CTimerManager::getInstance()->cancelShutdownOnWakeup(); } uint64_t now_pressed; bool keyok = true; tv = ev.time; now_pressed = (uint64_t) tv.tv_usec + (uint64_t)((uint64_t) tv.tv_sec * (uint64_t) 1000000); if (trkey == rc_last_key) { /* only allow selected keys to be repeated */ if (mayRepeat(trkey, bAllowRepeatLR) || (g_settings.shutdown_real_rcdelay && ((trkey == RC_standby) && (g_info.hw_caps->can_shutdown)))) { #ifdef ENABLE_REPEAT_CHECK if (rc_last_repeat_key != trkey) { if ((now_pressed > last_keypress + repeat_block) || /* accept all keys after time discontinuity: */ (now_pressed < last_keypress)) rc_last_repeat_key = trkey; else keyok = false; } #endif } else keyok = false; } else rc_last_repeat_key = KEY_MAX; rc_last_key = trkey; if (keyok) { #ifdef ENABLE_REPEAT_CHECK if ((now_pressed > last_keypress + repeat_block_generic) || /* accept all keys after time discontinuity: */ (now_pressed < last_keypress)) #endif { last_keypress = now_pressed; FILE* rclocked = fopen("/tmp/rc.locked", "r"); if (rclocked) { fclose(rclocked); continue; } *msg = trkey; *data = 0; /* <- button pressed */ if(g_settings.key_click) play_click(); return; } } /*if keyok */ } /* if (ev.value) */ else { // clear rc_last_key on keyup event rc_last_key = KEY_MAX; if (trkey == RC_standby) { *msg = RC_standby; *data = 1; /* <- button released */ return; } } }/* if FDSET */ } /* for NUMBER_OF_EVENT_DEVICES */ if(FD_ISSET(fd_pipe_low_priority[0], &rfds)) { struct event buf; read(fd_pipe_low_priority[0], &buf, sizeof(buf)); *msg = buf.msg; *data = buf.data; // printf("got event from low-pri pipe %x %x\n", *msg, *data ); return; } if ( InitialTimeout == 0 ) { //nicht warten wenn kein key da ist *msg = RC_timeout; *data = 0; return; } else { //timeout neu kalkulieren int64_t getKeyNow = time_monotonic_us(); int64_t diff = (getKeyNow - getKeyBegin); if( Timeout <= (uint64_t) diff ) { *msg = RC_timeout; *data = 0; return; } else Timeout -= diff; } } }
int msgYesNo(char *text, int default_opt, int x, int y) { int len = strlen(text); int X, Y; SDL_Rect src; SDL_Rect rc; SDL_Rect brc; uint32_t key; if (x < 0) X = (FULL_DISPLAY_X /2) - (len / 2 + 1)*12/RATIO; else X = x; if (y < 0) Y = (FULL_DISPLAY_Y /2) - 48/RATIO; else Y = y; rc.x=X; rc.y=Y; rc.w=12*(len + 2)/RATIO; rc.h=80/RATIO; src.x=rc.x+4/RATIO; src.y=rc.y+4/RATIO; src.w=rc.w; src.h=rc.h; while (1) { SDL_FillRect(real_screen, &src, SDL_MapRGB(real_screen->format, 116, 117, 206)); SDL_FillRect(real_screen, &rc, SDL_MapRGB(real_screen->format, 128, 128, 128)); menu_print_font(real_screen, 255,255,255, X+12/RATIO, Y+12/RATIO, text,20); if (default_opt) { brc.x=rc.x + rc.w/2-5*12/RATIO-2/RATIO; brc.y=rc.y+42/RATIO; brc.w=12*3/RATIO+4/RATIO; brc.h=22/RATIO; SDL_FillRect(real_screen, &brc, SDL_MapRGB(real_screen->format, 0x00, 0x80, 0x00)); } else { brc.x=rc.x + rc.w/2+5*12/RATIO-2*12/RATIO-8/RATIO; brc.y=rc.y+42/RATIO; brc.w=12*3/RATIO+4/RATIO; brc.h=22/RATIO; SDL_FillRect(real_screen, &brc, SDL_MapRGB(real_screen->format, 0x80, 0x00, 0x00)); } menu_print_font(real_screen, 255,255,255, rc.x + rc.w/2-5*12/RATIO, Y+42/RATIO, "YES",20); menu_print_font(real_screen, 255,255,255, rc.x + rc.w/2-5*12/RATIO+8*12/RATIO, Y+42/RATIO, "NO",20); SDL_UpdateRect(real_screen, src.x, src.y, src.w, src.h); SDL_UpdateRect(real_screen, rc.x, rc.y, rc.w,rc.h); SDL_UpdateRect(real_screen, brc.x, brc.y, brc.w,brc.h); //SDL_Flip(real_screen); key = menu_wait_key_press(); if (key & KEY_SELECT) { play_click(1); return default_opt; } else if (key & KEY_ESCAPE) { play_click(2); return 0; } else if (key & KEY_LEFT) { play_click(0); default_opt = !default_opt; } else if (key & KEY_RIGHT) { play_click(0); default_opt = !default_opt; } } }