From d7748fde181f9d28b42ce9c085c573da4cca7582 Mon Sep 17 00:00:00 2001 From: Marten Richter Date: Sun, 9 Sep 2012 11:41:44 +0200 Subject: [PATCH] libCEC support --- boxstack.cc | 2 +- boxx.cc | 8 +- log.cc | 0 osdopengl.cc | 7 +- osdopengl.h | 2 +- remotelinux.cc | 419 ++++++++++++++++++++++++++++++++++++++--------- remotelinux.h | 18 +- stream.cc | 2 +- surfaceopengl.cc | 17 +- 9 files changed, 375 insertions(+), 100 deletions(-) mode change 100755 => 100644 log.cc mode change 100755 => 100644 surfaceopengl.cc diff --git a/boxstack.cc b/boxstack.cc index 739dd5a..188a5ed 100644 --- a/boxstack.cc +++ b/boxstack.cc @@ -286,7 +286,7 @@ void BoxStack::update(Boxx* toUpdate, Region* regionToUpdate) boxes[z]->blt(r2); rl.pop_front(); } - + #ifndef WIN32 pthread_mutex_unlock(&boxLock); #else diff --git a/boxx.cc b/boxx.cc index 1705370..1e31c13 100644 --- a/boxx.cc +++ b/boxx.cc @@ -144,15 +144,15 @@ void Boxx::blt(Region& r) destination x on screen destination y on screen */ - + Log::getInstance()->log("Boxx", Log::DEBUG, "blt mark 1"); if (parent) abort(); // if (parent) then this is a child boxx. It can not blt. - + Log::getInstance()->log("Boxx", Log::DEBUG, "blt mark 2"); // this shouldn't be here r.x -= area.x; r.y -= area.y; - + Log::getInstance()->log("Boxx", Log::DEBUG, "blt mark 3"); surface->updateToScreen(r.x, r.y, r.w, r.h, area.x + r.x, area.y + r.y); - + Log::getInstance()->log("Boxx", Log::DEBUG, "blt mark 4"); } int Boxx::getScreenX() diff --git a/log.cc b/log.cc old mode 100755 new mode 100644 diff --git a/osdopengl.cc b/osdopengl.cc index b4bd06d..517b836 100644 --- a/osdopengl.cc +++ b/osdopengl.cc @@ -88,7 +88,7 @@ int OsdOpenGL::init(void* device) // May be this device specific part should go to a device specific child class //init broadcom chipset (Move to video?) - bcm_host_init(); + //First get connection to egl egl_display=eglGetDisplay(EGL_DEFAULT_DISPLAY); @@ -358,10 +358,12 @@ void OsdOpenGL::threadPostStopCleanup() void OsdOpenGL::InternalRendering(){ + BeginPainting(); + //InitVertexBuffer(display_width,display_height); InitVertexBuffer(1.f,1.f); @@ -386,12 +388,13 @@ void OsdOpenGL::InternalRendering(){ glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); - + //Show it to the user! eglSwapBuffers(egl_display, egl_surface); EndPainting(); + #ifdef BENCHMARK_FPS num_benchmark_frames++; if (getTimeMS()-last_benchmark_time>4000) { diff --git a/osdopengl.h b/osdopengl.h index 401889d..7802d57 100644 --- a/osdopengl.h +++ b/osdopengl.h @@ -23,7 +23,7 @@ #include -#include + #include #include diff --git a/remotelinux.cc b/remotelinux.cc index b31cbb7..8b643ea 100644 --- a/remotelinux.cc +++ b/remotelinux.cc @@ -29,6 +29,17 @@ #include #include +#include +#include +#include + +#include + +using namespace std; +using namespace CEC; + +#include + @@ -42,11 +53,11 @@ RemoteLinux::RemoteLinux() { initted = 0; - curevent=0; - hascurevent=false; + curcec=0; + hascurcec=false; signal=false; - tv.tv_sec = 0; - tv.tv_usec = 0; + cec_adap=NULL; + num_loop=0; } @@ -99,8 +110,63 @@ int RemoteLinux::init(char* devName) } + + + + } + // bcm_host_init(); //may be move to custom hardware init? +// now init cec + Log::getInstance()->log("Remote", Log::NOTICE, "Init LibCEC"); + cec_config.Clear(); + cec_callbacks.Clear(); + cec_callbacks.CBCecLogMessage = cecLogMessage; + cec_callbacks.CBCecKeyPress = cecKeyPress; + cec_callbacks.CBCecCommand = cecCommand; + cec_callbacks.CBCecConfigurationChanged = cecConfigurationChanged; + cec_config.clientVersion=LIBCEC_VERSION_CURRENT; + cec_config.bActivateSource=1; + cec_config.bUseTVMenuLanguage=1; + //cec_config.deviceTypes.Add(CEC_DEVICE_TYPE_PLAYBACK_DEVICE); + cec_config.deviceTypes.Add(CEC_DEVICE_TYPE_TUNER); + + strncpy(cec_config.strDeviceName,"vomp",sizeof(cec_config.strDeviceName)); + + + cec_config.callbackParam = NULL; // I do not care + cec_config.callbacks = &cec_callbacks; + + cec_adap = LibCecInitialise(&cec_config); + if (!cec_adap) { + Log::getInstance()->log("Remote", Log::ERR, "Init LibCEC failed"); + return 1; + } + cec_adap->InitVideoStandalone(); + + + cec_adapter cec_devices[10]; + int adap_num=cec_adap->FindAdapters(cec_devices,10,NULL); + if (adap_num<0) { + Log::getInstance()->log("Remote", Log::ERR, "CEC:Failed to find adapter"); + return 1; + + } + if (adap_num==0) { + Log::getInstance()->log("Remote", Log::NOTICE, "CEC: No adapter found"); + return 1; + + } + if (!cec_adap->Open(cec_devices[0].comm)) { + Log::getInstance()->log("Remote", Log::ERR, "CEC:Failed to open adapter"); + return 1; + } + + if (!cec_adap->SetActiveSource(cec_config.deviceTypes[0])) { + Log::getInstance()->log("Remote", Log::ERR, "CEC:Failed set active source"); + return 1; + } + @@ -110,85 +176,102 @@ int RemoteLinux::init(char* devName) int RemoteLinux::shutdown() { if (!initted) return 0; + if (cec_adap) { + cec_adap->SetInactiveView(); + cec_adap->Close(); + UnloadLibCec(cec_adap); + } initted = 0; return 1; } -UCHAR RemoteLinux::getButtonPress(int waitType) -{ - /* how = 0 - block - how = 1 - start new wait - how = 2 - continue wait - how = 3 - no wait - */ - - - struct timeval* passToSelect = NULL; - int retval; - fd_set readfds; - - if (waitType == 0) - { - passToSelect = NULL; - } - else if (waitType == 1) - { - tv.tv_sec = 1; - tv.tv_usec = 000000; - passToSelect = &tv; - } - else if (waitType == 2) - { - if ((tv.tv_sec == 0) && (tv.tv_usec == 0)) // protection in case timer = 0 - { - tv.tv_sec = 1; - tv.tv_usec = 000000; - } - passToSelect = &tv; - } - else if (waitType == 3) - { - tv.tv_sec = 0; - tv.tv_usec = 0; - passToSelect = &tv; - } - FD_ZERO(&readfds); - - int maxfd=0; - for (int i=0; ilog("Remote", Log::NOTICE, "na_signal"); + return NA_SIGNAL; + + } + for (int i = 0; i < devices.size(); i++) { + int cur_fd = devices[i]; + if (FD_ISSET(cur_fd, &readfds)) { + struct input_event ev; + int count = read(cur_fd, &ev, sizeof(ev)); + if (count == sizeof(ev)) { + if (ev.type == EV_KEY && ev.value == 1) { + UCHAR retty=(UCHAR) TranslateHWC( + W_G_HCW(W_HCW_KC,ev.code)); + return retty; + } + } + + } + + } + + } + //Log::getInstance()->log("Remote", Log::NOTICE, "numloop: %d %d",num_loop,retval); + if (num_loop > 0) + num_loop--; + } + if (ret != 0) + return ret; - } + return NA_UNKNOWN; - } - - return NA_UNKNOWN; - } void RemoteLinux::clearBuffer() @@ -216,6 +299,25 @@ UCHAR RemoteLinux::TranslateHWCFixed(ULLONG code) case W_G_HCW(W_HCW_KC,KEY_SPACE): case W_G_HCW(W_HCW_KC,KEY_OK): return OK; + //CEC + case W_G_HCW(W_HCW_CEC,CEC_USER_CONTROL_CODE_DOWN): + return DOWN; + case W_G_HCW(W_HCW_CEC,CEC_USER_CONTROL_CODE_UP): + return UP; + case W_G_HCW(W_HCW_CEC,CEC_USER_CONTROL_CODE_LEFT): + return LEFT; + case W_G_HCW(W_HCW_CEC,CEC_USER_CONTROL_CODE_RIGHT): + return RIGHT; + case W_G_HCW(W_HCW_CEC,CEC_USER_CONTROL_CODE_ROOT_MENU): + case W_G_HCW(W_HCW_CEC,CEC_USER_CONTROL_CODE_CONTENTS_MENU): + case W_G_HCW(W_HCW_CEC,CEC_USER_CONTROL_CODE_SETUP_MENU): + return MENU; + case W_G_HCW(W_HCW_CEC,CEC_USER_CONTROL_CODE_EXIT ): + return BACK; + case W_G_HCW(W_HCW_CEC,CEC_USER_CONTROL_CODE_ENTER): + case W_G_HCW(W_HCW_CEC,CEC_USER_CONTROL_CODE_SELECT): + case W_G_HCW(W_HCW_CEC,CEC_USER_CONTROL_CODE_AN_RETURN): + return OK; case POWER: return POWER; default: @@ -326,12 +428,54 @@ void RemoteLinux::InitHWCListwithDefaults() translist[W_G_HCW(W_HCW_KC,KEY_PAGEDOWN)] = CHANNELDOWN; + //Processing CEC_Messages + translist[W_G_HCW(W_HCW_CEC,CEC_USER_CONTROL_CODE_NUMBER9)] = NINE; + translist[W_G_HCW(W_HCW_CEC,CEC_USER_CONTROL_CODE_NUMBER8)] = EIGHT; + translist[W_G_HCW(W_HCW_CEC,CEC_USER_CONTROL_CODE_NUMBER7)] = SEVEN; + translist[W_G_HCW(W_HCW_CEC,CEC_USER_CONTROL_CODE_NUMBER6)] = SIX; + translist[W_G_HCW(W_HCW_CEC,CEC_USER_CONTROL_CODE_NUMBER5)] = FIVE; + translist[W_G_HCW(W_HCW_CEC,CEC_USER_CONTROL_CODE_NUMBER4)] = FOUR; + translist[W_G_HCW(W_HCW_CEC,CEC_USER_CONTROL_CODE_NUMBER3)] = THREE; + translist[W_G_HCW(W_HCW_CEC,CEC_USER_CONTROL_CODE_NUMBER2)] = TWO; + translist[W_G_HCW(W_HCW_CEC,CEC_USER_CONTROL_CODE_NUMBER1)] = ONE; + translist[W_G_HCW(W_HCW_CEC,CEC_USER_CONTROL_CODE_NUMBER0)] = ZERO; + translist[W_G_HCW(W_HCW_CEC,KEY_KPDOT)] = STAR; + + + + //translist[W_G_HCW(W_HCW_CEC,KEY_J)] = GO; //j for JUMP TO instead of go to + translist[W_G_HCW(W_HCW_CEC,CEC_USER_CONTROL_CODE_F2_RED)] = RED; + translist[W_G_HCW(W_HCW_CEC,CEC_USER_CONTROL_CODE_F3_GREEN)] = GREEN; + translist[W_G_HCW(W_HCW_CEC,CEC_USER_CONTROL_CODE_F4_YELLOW)] = YELLOW; + translist[W_G_HCW(W_HCW_CEC,CEC_USER_CONTROL_CODE_F1_BLUE)] = BLUE; + //Processing Remote Style Messages + translist[W_G_HCW(W_HCW_CEC,CEC_USER_CONTROL_CODE_FAVORITE_MENU)] = MENU; + + translist[W_G_HCW(W_HCW_CEC,CEC_USER_CONTROL_CODE_RECORD)] = RECORD; + translist[W_G_HCW(W_HCW_CEC,CEC_USER_CONTROL_CODE_PLAY)] = PLAY; //Playback Televison + translist[W_G_HCW(W_HCW_CEC,CEC_USER_CONTROL_CODE_PAUSE)] = PAUSE; + translist[W_G_HCW(W_HCW_CEC,CEC_USER_CONTROL_CODE_STOP)] = STOP; + translist[W_G_HCW(W_HCW_CEC,CEC_USER_CONTROL_CODE_PAUSE_PLAY_FUNCTION)] = PLAYPAUSE; + translist[W_G_HCW(W_HCW_CEC,CEC_USER_CONTROL_CODE_FORWARD)] = SKIPFORWARD; + translist[W_G_HCW(W_HCW_CEC,CEC_USER_CONTROL_CODE_BACKWARD)] = SKIPBACK; + translist[W_G_HCW(W_HCW_CEC,CEC_USER_CONTROL_CODE_FAST_FORWARD )] = FORWARD; + translist[W_G_HCW(W_HCW_CEC,CEC_USER_CONTROL_CODE_REWIND)] = REVERSE; + translist[W_G_HCW(W_HCW_CEC,CEC_USER_CONTROL_CODE_MUTE)] = MUTE; + translist[W_G_HCW(W_HCW_CEC,CEC_USER_CONTROL_CODE_VOLUME_UP)] = VOLUMEUP; + translist[W_G_HCW(W_HCW_CEC,CEC_USER_CONTROL_CODE_VOLUME_DOWN)] = VOLUMEDOWN; + translist[W_G_HCW(W_HCW_CEC,CEC_USER_CONTROL_CODE_CHANNEL_UP )] = CHANNELUP; + translist[W_G_HCW(W_HCW_CEC,CEC_USER_CONTROL_CODE_CHANNEL_DOWN)] = CHANNELDOWN; + + + } #define NAMETRICK(pre, code) linux_keymap[pre ## code]= #code +#define NAMETRICK2(pre, code) cec_keymap[pre ## code]= #code //extracte from linux/input.h static const char * linux_keymap[KEY_MAX+1]; +static const char * cec_keymap[CEC_USER_CONTROL_CODE_MAX+1]; void RemoteLinux::InitKeymap() { @@ -576,7 +720,90 @@ void RemoteLinux::InitKeymap() NAMETRICK(KEY_,NUMERIC_STAR); NAMETRICK(KEY_,NUMERIC_POUND); - + for (int i=0;ilog("Remote", Log::DEBUG, "CECLOG: %lld %d %s",message.time , message.level, message.message ); + return 0; +} +int RemoteLinux::cecKeyPress(void*param, const cec_keypress &key) +{ + //Log::getInstance()->log("Remote", Log::DEBUG, "Incoming cec key %d %d", key.keycode,key.duration); + if (key.duration==0) ((RemoteLinux*)Remote::getInstance())->incomingCECkey(key.keycode); + return 1; +} +int RemoteLinux::cecCommand(void *param, const cec_command &command) +{ + //Log::getInstance()->log("Remote", Log::DEBUG, "CECCommand: %d",command.opcode); + return 1; +} + +int RemoteLinux::cecConfigurationChanged(void *param, const libcec_configuration &config) +{ + //Log::getInstance()->log("Remote", Log::DEBUG, "CECConfig:"/*,config.string()*/); + return 1; +} +void RemoteLinux::incomingCECkey(int keys) +{ + curcec=keys; + hascurcec=true; +} /* void RemoteLinux::Signal() { diff --git a/remotelinux.h b/remotelinux.h index c4f3ffa..e45cac4 100644 --- a/remotelinux.h +++ b/remotelinux.h @@ -28,6 +28,7 @@ #include "remote.h" #include +#include @@ -56,13 +57,24 @@ class RemoteLinux : public Remote private: int initted; bool signal; - UCHAR curevent; - bool hascurevent; + int curcec; + bool hascurcec; UCHAR TranslateHWCFixed(ULLONG code); void InitKeymap(); vector devices; - struct timeval tv; + int num_loop; + + CEC::ICECAdapter * cec_adap; + CEC::libcec_configuration cec_config; + CEC::ICECCallbacks cec_callbacks; + + void incomingCECkey(int keys); + + static int cecLogMessage(void *param, const CEC::cec_log_message &message); + static int cecKeyPress(void*param, const CEC::cec_keypress &key); + static int cecCommand(void *param, const CEC::cec_command &command); + static int cecConfigurationChanged(void *param, const CEC::libcec_configuration &config); }; diff --git a/stream.cc b/stream.cc index c7b5e70..abea315 100644 --- a/stream.cc +++ b/stream.cc @@ -154,7 +154,7 @@ int Stream::put(const UCHAR* inbuf, int len, UCHAR type,unsigned int index) mediapackets.push_back(newPacket); unLock(); } else { - Log::getInstance()->log("Stream", Log::DEBUG, "We are full %d!",bufferSize); + // Log::getInstance()->log("Stream", Log::DEBUG, "We are full %d!",bufferSize); } return ret; diff --git a/surfaceopengl.cc b/surfaceopengl.cc old mode 100755 new mode 100644 index ad5fbfe..df2eb8d --- a/surfaceopengl.cc +++ b/surfaceopengl.cc @@ -210,28 +210,31 @@ void SurfaceOpenGL::drawBitmap(int x, int y, const Bitmap& bm) int SurfaceOpenGL::updateToScreen(int sx, int sy, int w, int h, int dx, int dy) // FIXME new, replace others with this FIXME { +// Log::getInstance()->log("Surface", Log::WARN, "UTS Mark1"); srf_mutex.Lock();//since this might be called before surface //allocation we will wait in this case, hopefully without deadlocks - /* if (!d3dsurface) { - return 0; //why does this happen - }*/ - OsdOpenGL* osd=((OsdOpenGL*)(Osd::getInstance())); + OsdOpenGL* osd=((OsdOpenGL*)(Osd::getInstance())); + // Log::getInstance()->log("Surface", Log::WARN, "UTS Mark2"); GLuint screengltexture=((SurfaceOpenGL*)screen)->getTexture(); osd->BeginPainting(); + // Log::getInstance()->log("Surface", Log::WARN, "UTS Mark3"); glBindTexture(GL_TEXTURE_2D, screengltexture); - //Log::getInstance()->log("Surface", Log::WARN, "UTS Mark3 %d",glGetError()); +// Log::getInstance()->log("Surface", Log::WARN, "UTS Mark4 %d",glGetError()); for (int y=0;ylog("Surface", Log::WARN, "UTS Mark4a %d %d %d %d %d %d",sx,sy,w,h,dx,dy); glTexSubImage2D(GL_TEXTURE_2D,0,dx,(dy+y),w,1,GL_RGBA,GL_UNSIGNED_BYTE, data+((y+sy)*swidth+sx)*sizeof(uint32_t)); - // Log::getInstance()->log("Surface", Log::WARN, "UTS Mark43 %d",glGetError()); + } - //Log::getInstance()->log("Surface", Log::WARN, "UTS Mark4 %d",glGetError()); + osd->EndPainting(); + srf_mutex.Unlock(); + return 0; } -- 2.39.2