int cec_done(int poweroff) { if (poweroff) { /* Power-off the TV */ cec_standby_devices(CEC_DEFAULT_BASE_DEVICE); } /* Cleanup */ cec_destroy(); return 0; }
int cec_init(int init_video) { int res; /* Set the CEC configuration */ clear_config(&cec_config); snprintf(cec_config.strDeviceName, 13, "pidvbip"); cec_config.clientVersion = CEC_CONFIG_VERSION; cec_config.bActivateSource = 0; /* Say we are a recording/tuner/playback device */ cec_config.deviceTypes.types[0] = CEC_DEVICE_TYPE_RECORDING_DEVICE; /* Set the callbacks */ clear_callbacks(&cec_callbacks); cec_callbacks.CBCecLogMessage = &CecLogMessage; cec_callbacks.CBCecKeyPress = &CecKeyPress; cec_callbacks.CBCecCommand = &CecCommand; cec_callbacks.CBCecAlert = &CecAlert; cec_callbacks.CBCecSourceActivated= &CecSourceActivated; cec_config.callbacks = &cec_callbacks; /* Initialise the library */ if (!cec_initialise(&cec_config)) { fprintf(stderr,"Error initialising libcec, aborting\n"); return 1; } if (init_video) { /* init video on targets that need this */ cec_init_video_standalone(); } /* Locate CEC device */ cec_adapter devices[10]; int nadapters = cec_find_adapters(devices, 10, NULL); if (nadapters <= 0) { fprintf(stderr,"Error, no CEC adapters found.\n"); cec_destroy(); return 2; } if (nadapters > 1) { fprintf(stderr,"WARNING: %d adapters found, using first.\n",nadapters); } fprintf(stderr,"Using CEC adapter \"%s\", path=\"%s\"\n",devices[0].comm,devices[0].path); /* Open device with a 10000ms (10s) timeout */ if (!cec_open(devices[0].comm, CEC_DEFAULT_CONNECT_TIMEOUT)) { fprintf(stderr,"Error, cannot open device %s\n",devices[0].comm); cec_destroy(); return 3; } /* Enable callbacks, first parameter is the callback data passed to every callback */ cec_enable_callbacks(NULL, &cec_callbacks); /* Get the menu language of the TV */ cec_menu_language language; cec_get_device_menu_language(CEC_DEFAULT_BASE_DEVICE, &language); fprintf(stderr,"TV menu language: \"%c%c%c\"\n",language.language[0],language.language[1],language.language[2]); /* Get the power status of the TV */ cec_power_status power_status = cec_get_device_power_status(CEC_DEFAULT_BASE_DEVICE); fprintf(stderr,"TV Power Status: %d\n",power_status); /* Select ourselves as the source - this will also power-on the TV if needed */ fprintf(stderr,"Setting ourselves as the source\n"); cec_set_active_source(CEC_DEVICE_TYPE_RECORDING_DEVICE); /* Clear the keypress queue */ key_queue.numkeys = 0; pthread_mutex_init(&key_queue.mutex,NULL); return 0; }
int main (int argc, char *argv[]) { // Set default log level set_log_level(LOG_LEVEL_INFO); // Init ceclaunchd config config_t config; memset(config.device, 0, PATH_MAX); strncpy(config.logfile, DEFAULT_LOG_FILE, sizeof(config.logfile)); strncpy(config.pidfile, DEFAULT_PID_FILE, sizeof(config.pidfile)); config.debug = 0; config.daemonize = 0; config.keymap = NULL; config.last_keypress = NULL; log_info("Parsing config at '%s'.\n", CONF_FILE); if(!parse_config(&config, CONF_FILE)) { log_error("Could not parse config at %s\n", CONF_FILE); return 1; } log_open(config.logfile); if(!log_enabled()) { log_error("Could not open log file %s\n", config.logfile); } set_log_level(config.debug ? LOG_LEVEL_DEBUG : LOG_LEVEL_INFO); if(argc > 1 && !strcmp(argv[1], "-d")) { log_info("Activating daemoninzation! Bye bye! ;-)\n"); FILE *pid_fid; if(daemon(0, 0) < 0) { log_error("Could not deamonize: %s\n", strerror(errno)); return 1; } /* write our PID to the pidfile */ if((pid_fid = fopen(config.pidfile, "w"))) { fprintf(pid_fid, "%d\n", getpid()); fclose(pid_fid); } else { log_error("Could not create pid file %s: %s\n", config.pidfile, strerror(errno)); } } // Init libcec callbacks ICECCallbacks cec_callbacks; cec_callbacks.CBCecLogMessage = NULL; //&log_callback; cec_callbacks.CBCecKeyPress = &key_callback; cec_callbacks.CBCecCommand = NULL; cec_callbacks.CBCecConfigurationChanged = NULL; cec_callbacks.CBCecAlert = &alert_callback; cec_callbacks.CBCecMenuStateChanged = NULL; cec_callbacks.CBCecSourceActivated = NULL; // Init libcec config libcec_configuration cec_config; cec_config.iPhysicalAddress = CEC_PHYSICAL_ADDRESS_TV; cec_config.baseDevice = (cec_logical_address)CEC_DEFAULT_BASE_DEVICE; cec_config.iHDMIPort = CEC_DEFAULT_HDMI_PORT; cec_config.tvVendor = (uint64_t)CEC_VENDOR_UNKNOWN; cec_config.clientVersion = (uint32_t)CEC_CLIENT_VERSION_CURRENT; cec_config.serverVersion = (uint32_t)CEC_SERVER_VERSION_CURRENT; cec_config.bAutodetectAddress = 0; cec_config.bGetSettingsFromROM = CEC_DEFAULT_SETTING_GET_SETTINGS_FROM_ROM; cec_config.bUseTVMenuLanguage = CEC_DEFAULT_SETTING_USE_TV_MENU_LANGUAGE; cec_config.bActivateSource = 0; cec_config.bPowerOffScreensaver = CEC_DEFAULT_SETTING_POWER_OFF_SCREENSAVER; cec_config.bPowerOnScreensaver = CEC_DEFAULT_SETTING_POWER_ON_SCREENSAVER; cec_config.bPowerOffOnStandby = CEC_DEFAULT_SETTING_POWER_OFF_ON_STANDBY; cec_config.bShutdownOnStandby = CEC_DEFAULT_SETTING_SHUTDOWN_ON_STANDBY; cec_config.bSendInactiveSource = CEC_DEFAULT_SETTING_SEND_INACTIVE_SOURCE; cec_config.iFirmwareVersion = CEC_FW_VERSION_UNKNOWN; cec_config.bPowerOffDevicesOnStandby = CEC_DEFAULT_SETTING_POWER_OFF_DEVICES_STANDBY; strncpy(cec_config.strDeviceName, "ceclaunchd", sizeof(cec_config.strDeviceName)); cec_config.iFirmwareBuildDate = CEC_FW_BUILD_UNKNOWN; cec_config.bMonitorOnly = 0; cec_config.cecVersion = (cec_version)CEC_DEFAULT_SETTING_CEC_VERSION; cec_config.adapterType = ADAPTERTYPE_UNKNOWN; cec_config.iDoubleTapTimeoutMs = CEC_DOUBLE_TAP_TIMEOUT_MS; cec_config.comboKey = CEC_USER_CONTROL_CODE_STOP; cec_config.iComboKeyTimeoutMs = 0; // Disable combo key //cec_config.deviceTypes.types[0] = CEC_DEVICE_TYPE_PLAYBACK_DEVICE; cec_config.deviceTypes.types[0] = CEC_DEVICE_TYPE_RECORDING_DEVICE; for (unsigned int i = 1; i < 5; i++) { cec_config.deviceTypes.types[i] = CEC_DEVICE_TYPE_RESERVED; } cec_config.logicalAddresses.primary = CECDEVICE_UNREGISTERED; for (int i = 0; i < 16; i++) { cec_config.logicalAddresses.addresses[i] = 0; } cec_config.wakeDevices.primary = CECDEVICE_TV; for (int i = 0; i < 16; i++) { cec_config.wakeDevices.addresses[i] = 0; } cec_config.wakeDevices.addresses[CECDEVICE_TV] = 1; cec_config.powerOffDevices.primary = CECDEVICE_BROADCAST; for (int i = 0; i < 16; i++){ cec_config.powerOffDevices.addresses[i] = 0; } cec_config.powerOffDevices.addresses[CECDEVICE_BROADCAST] = 1; cec_config.callbackParam = &config; cec_config.callbacks = &cec_callbacks; //cec_enable_callbacks((void*) &config, cks *callbacks) log_info("Intialising and connecting to HDMI CEC device.\n", CONF_FILE); // Initialise libcec if(!cec_initialise(&cec_config)){ log_error("Cannot initialise libcec."); cec_destroy(); return 1; } cec_init_video_standalone(); // Run autodectect if(!strlen(config.device)) { cec_adapter_descriptor device_list[1]; if (cec_detect_adapters(device_list, 1, NULL, 1) < 1) { log_error("Autodetected failed.\n"); cec_destroy(); return 1; } strncpy(config.device, device_list[0].strComName, PATH_MAX-1); config.device[PATH_MAX-1] = '\0'; log_info("Autodetected %s (%s).\n", device_list[0].strComName, device_list[0].strComPath); } if (!cec_open(config.device, 1000)) { log_error("Could not open adapter %s.\n", config.device); cec_close(); cec_destroy(); return 1; } if(signal(SIGINT, &signal_handler) == SIG_ERR || signal(SIGTERM, &signal_handler) == SIG_ERR) { log_error("Could not register signal handler: %s\n", strerror(errno)); cec_close(); cec_destroy(); return 1; } log_info("Finished init.\n"); while(g_running) { if(config.last_keypress != NULL) { log_info("Running '%s'.\n", config.last_keypress->command); if(config.last_keypress->blocker) { cec_close(); system(config.last_keypress->command); if (!cec_open(config.device, 1000)) { log_error("Could not reopen adapter %s. Set blocker property for processes using libcec.\n", config.device); g_running = 0; } } else { pid_t pID = fork(); if (pID == 0) { //child execl("/bin/sh", "sh", "-c", config.last_keypress->command, (char *) 0); } else if (pID < 0) { log_error("Could not fork: %s\n", strerror(errno)); g_running = 0; } } config.last_keypress = NULL; } usleep(100); } log_info("Shutting down.\n"); cec_close(); cec_destroy(); log_close(); return 0; }