QOpenKODEIntegration::QOpenKODEIntegration() : mEventLoopIntegration(0) , mFontDb(new QGenericUnixFontDatabase()) , mMainGlContext(0) { if (kdInitializeNV() == KD_ENOTINITIALIZED) { qFatal("Did not manage to initialize openkode"); } KDDisplaySystemNV *kdDisplaySystem = kdCreateDisplaySystemSnapshotNV(this); KDint32 displayCount = 0; kdGetDisplaySystemPropertyivNV(kdDisplaySystem, KD_DISPLAYPROPERTY_COUNT_NV, 0, &displayCount); for (int i = 0; i < displayCount; i++) { KDchar *displayName = 0; KDsize displayNameLength = 0; kdGetDisplaySystemPropertycvNV(kdDisplaySystem,KD_DISPLAYPROPERTY_NAME_NV,i,0,&displayNameLength); if (!displayNameLength) continue; displayName = new KDchar[displayNameLength]; kdGetDisplaySystemPropertycvNV(kdDisplaySystem,KD_DISPLAYPROPERTY_NAME_NV,i,displayName,&displayNameLength); KDDisplayNV *display = kdGetDisplayNV(displayName,this); if (!display || display == (void*)-1) { qErrnoWarning(kdGetError(), "Could not obtain KDDisplayNV pointer"); return; } if (displayNameLength) delete displayName; KDchar *desktopName = 0; KDsize desktopNameLength = 0; bool openkodeImpDoesNotFail = false; if (openkodeImpDoesNotFail) { qDebug() << "printing desktopname"; kdGetDisplayPropertycvNV(display,KD_DISPLAYPROPERTY_DESKTOP_NAME_NV,desktopName,&desktopNameLength); if (desktopNameLength) { desktopName = new KDchar[desktopNameLength]; kdGetDisplayPropertycvNV(display,KD_DISPLAYPROPERTY_DESKTOP_NAME_NV,desktopName,&desktopNameLength); } else { desktopName = KD_DEFAULT_DESKTOP_NV; } } else { desktopName = KD_DEFAULT_DESKTOP_NV; } KDDesktopNV *desktop = kdGetDesktopNV(desktopName,this); if (!desktop || desktop == (void*)-1) { qErrnoWarning(kdGetError(), "Could not obtain KDDesktopNV pointer"); kdReleaseDisplayNV(display); return; } if (desktopNameLength) delete desktopName; QOpenKODEScreen *screen = new QOpenKODEScreen(display,desktop); mScreens.append(screen); } }
QT_BEGIN_NAMESPACE QOpenKODEScreen::QOpenKODEScreen(KDDisplayNV *kdDisplay, KDDesktopNV *kdDesktop) : mIsFullScreen(false) { qDebug() << "QOpenKODEScreen::QOpenKODEIntegrationScreen()"; KDboolean enabled = KD_TRUE; kdSetDisplayPropertybvNV(kdDisplay, KD_DISPLAYPROPERTY_ENABLED_NV, &enabled); KDboolean power = KD_DISPLAY_POWER_ON; kdSetDisplayPropertyivNV(kdDisplay, KD_DISPLAYPROPERTY_POWER_NV, &power); kdSetDisplayPropertycvNV(kdDisplay, KD_DISPLAYPROPERTY_DESKTOP_NAME_NV, KD_DEFAULT_DESKTOP_NV); KDDisplayModeNV mode; if (kdGetDisplayModeNV(kdDisplay, &mode)) { qErrnoWarning(kdGetError(), "Could not get display mode"); return; } qDebug() << " - display mode " << mode.width << "x" << mode.height << " refresh " << mode.refresh; KDint desktopSize[] = { mode.width, mode.height }; if (kdSetDesktopPropertyivNV(kdDesktop, KD_DESKTOPPROPERTY_SIZE_NV, desktopSize)) { qErrnoWarning(kdGetError(), "Could not set desktop size"); return; } // Once we've set up the desktop and display we don't need them anymore kdReleaseDisplayNV(kdDisplay); kdReleaseDesktopNV(kdDesktop); mEglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY); if (mEglDisplay == EGL_NO_DISPLAY) { qErrnoWarning("EGL failed to obtain display"); } /* Initialize EGL display */ EGLBoolean rvbool = eglInitialize(mEglDisplay, 0, 0); if (!rvbool) { qErrnoWarning("EGL failed to initialize display"); } // cursor = new QOpenKODECursor(this); mGeometry = QRect(0, 0, mode.width, mode.height); mDepth = 24; mFormat = QImage::Format_RGB32; }
bool CWinSystemEGL::DestroyWindow() { EGLBoolean eglStatus; if (m_context != EGL_NO_CONTEXT) { eglStatus = eglDestroyContext(m_display, m_context); if (!eglStatus) CLog::Log(LOGERROR, "Error destroying EGL context"); m_context = EGL_NO_CONTEXT; } if (m_surface != EGL_NO_SURFACE) { eglStatus = eglDestroySurface(m_display, m_surface); if (!eglStatus) CLog::Log(LOGERROR, "Error destroying EGL surface"); m_surface = EGL_NO_SURFACE; } if (m_display != EGL_NO_DISPLAY) { eglStatus = eglTerminate(m_display); if (!eglStatus) CLog::Log(LOGERROR, "Error terminating EGL"); m_display = EGL_NO_DISPLAY; } #ifdef HAS_OPENKODE if (m_kdWindow) { if (kdDestroyWindow(m_kdWindow)) CLog::Log(LOGERROR, "Error destroying native window"); m_kdWindow = KD_NULL; m_nativeWindow = (NativeWindowType)0; } // Release display if (m_kdDisplay) { if (kdReleaseDisplayNV(m_kdDisplay)) CLog::Log(LOGERROR, "Error destroying native display"); m_kdDisplay = KD_NULL; } #endif return true; }
bool CWinSystemEGL::CreateNewWindow(const CStdString& name, bool fullScreen, RESOLUTION_INFO& res, PHANDLE_EVENT_FUNC userFunction) { #if defined(EMPOWER) && defined(HAS_OPENKODE) KDboolean b; KDDisplayModeNV mode; KDint desktopSize[2] = { res.iWidth, res.iHeight }; #endif #ifdef _WIN32 EGL_BASE_CLASS::CreateNewWindow(name, fullScreen, res, userFunction); #endif m_nWidth = res.iWidth; m_nHeight = res.iHeight; m_bFullScreen = fullScreen; EGLBoolean eglStatus; EGLint configCount; EGLConfig* configList = NULL; #if defined(EMPOWER) && defined(HAS_OPENKODE) //CLog::Log(LOGDEBUG, "NV: GetDisplay"); m_kdDisplay = kdGetDisplayNV(KD_DEFAULT_DISPLAY_NV, KD_NULL); if (!m_kdDisplay) { CLog::Log(LOGERROR, "Could not obtain KDDisplayNV pointer"); return false; } b = KD_FALSE; //CLog::Log(LOGDEBUG, "NV: SetDisplayProperty"); kdSetDisplayPropertybvNV(m_kdDisplay, KD_DISPLAYPROPERTY_ENABLED_NV, &b); kdReleaseDisplayNV(m_kdDisplay); // MZL: enable HDMI display //CLog::Log(LOGDEBUG, "NV: SetDisplayPropertybyNV"); kdSetDisplayPropertybvNV(m_kdDisplay, KD_DISPLAYPROPERTY_ENABLED_NV, &b); m_kdDisplay = kdGetDisplayNV("Tegra:HDMI0", KD_NULL); if (!m_kdDisplay) { CLog::Log(LOGERROR, "Could not obtain KDDisplayNV pointer"); return false; } b = KD_TRUE; kdSetDisplayPropertybvNV(m_kdDisplay, KD_DISPLAYPROPERTY_ENABLED_NV, &b); kdSetDisplayPropertycvNV(m_kdDisplay, KD_DISPLAYPROPERTY_DESKTOP_NAME_NV, KD_DEFAULT_DESKTOP_NV); mode.width = res.iWidth; mode.height = res.iHeight; mode.refresh = 60; //CLog::Log(LOGDEBUG, "NV: SetDisplayPropertyNV"); if (kdSetDisplayModeNV(m_kdDisplay, &mode, KD_DISPLAY_PROTOCOL_AUTOMATIC_NV)) { CLog::Log(LOGERROR, "Could not set display mode\n"); return false; } //CLog::Log(LOGDEBUG, "NV: GetDesktopNV"); m_kdDesktop = kdGetDesktopNV(KD_DEFAULT_DESKTOP_NV, KD_NULL); if (!m_kdDesktop) { CLog::Log(LOGERROR, "Could not obtain KDDesktopNV pointer"); return false; } //CLog::Log(LOGDEBUG, "NV: SetDesktopivNV"); if (kdSetDesktopPropertyivNV(m_kdDesktop, KD_DESKTOPPROPERTY_SIZE_NV, desktopSize)) { CLog::Log(LOGERROR, "Could not set desktop size"); return false; } #endif #ifdef HAS_X11 m_x11Display = XOpenDisplay(NULL); if (!m_x11Display) { CLog::Log(LOGERROR, "Could not open X11"); return false; } XSetErrorHandler(ApplicationErrorHandler) ; #endif //CLog::Log(LOGDEBUG, "eglGetDisplay"); #if defined(HAS_OPENKODE) || defined(HAS_GDL) m_display = eglGetDisplay(EGL_DEFAULT_DISPLAY); #elif defined(_WIN32) m_display = eglGetDisplay(m_hDC); #elif defined(HAS_X11) m_display = eglGetDisplay((EGLNativeDisplayType) m_x11Display); #endif if (m_display == EGL_NO_DISPLAY) { CLog::Log(LOGERROR, "EGL failed to obtain display"); return false; } //CLog::Log(LOGDEBUG, "eglInitialize"); if (!eglInitialize(m_display, 0, 0)) { CLog::Log(LOGERROR, "EGL failed to initialize"); return false; } EGLint configAttrs[] = { EGL_RED_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_BLUE_SIZE, 8, EGL_DEPTH_SIZE, 16, EGL_STENCIL_SIZE, 8, EGL_SAMPLE_BUFFERS, 0, EGL_SAMPLES, 0, EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, EGL_NONE }; // Find out how many configurations suit our needs //CLog::Log(LOGDEBUG, "eglChooseConfig"); eglStatus = eglChooseConfig(m_display, configAttrs, NULL, 0, &configCount); if (!eglStatus || !configCount) { CLog::Log(LOGERROR, "EGL failed to return any matching configurations"); return false; } // Allocate room for the list of matching configurations configList = (EGLConfig*)malloc(configCount * sizeof(EGLConfig)); if (!configList) { CLog::Log(LOGERROR, "kdMalloc failure obtaining configuration list"); return false; } // Obtain the configuration list from EGL eglStatus = eglChooseConfig(m_display, configAttrs, configList, configCount, &configCount); if (!eglStatus || !configCount) { CLog::Log(LOGERROR, "EGL failed to populate configuration list"); return false; } // Select an EGL configuration that matches the native window m_config = configList[0]; EGLint* attribList = NULL; #ifdef EMPOWER EGLint windowAttrs[3]; int windowIndex = 0; windowAttrs[windowIndex++] = EGL_RENDER_BUFFER; windowAttrs[windowIndex++] = EGL_BACK_BUFFER; windowAttrs[windowIndex++] = EGL_NONE; attribList = windowAttrs; #endif #ifdef HAS_OPENKODE //CLog::Log(LOGDEBUG, "KD: kdCreateWindow"); m_kdWindow = kdCreateWindow(m_display, m_config, KD_NULL); if (!m_kdWindow) { CLog::Log(LOGERROR, "Error creating native window"); return false; } //CLog::Log(LOGDEBUG, "KD: kdRealizeWindow"); if (kdRealizeWindow(m_kdWindow, &m_nativeWindow)) { CLog::Log(LOGERROR, "Could not realize native window"); return false; } #elif defined HAS_X11 int screen = DefaultScreen(m_x11Display); XSetWindowAttributes windowAttributes; windowAttributes.colormap = DefaultColormap(m_x11Display, screen); windowAttributes.border_pixel = 0; windowAttributes.event_mask = ExposureMask | VisibilityChangeMask | KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | PointerMotionMask | StructureNotifyMask | SubstructureNotifyMask | FocusChangeMask; m_nativeWindow = (NativeWindowType) XCreateWindow( m_x11Display, RootWindow(m_x11Display, screen), 0, 0, // x/y position of top-left outside corner of the window res.iWidth, res.iHeight, // Width and height of window 0, // Border width DefaultDepth(m_x11Display, screen), InputOutput, DefaultVisual(m_x11Display, screen), CWBorderPixel | CWColormap | CWEventMask, &windowAttributes ); XSetStandardProperties(m_x11Display, (Window) m_nativeWindow, name, name, None, NULL, 0, NULL); Atom wmDeleteMessage = XInternAtom(m_x11Display, "WM_DELETE_WINDOW", False); XSetWMProtocols(m_x11Display, (Window) m_nativeWindow, &wmDeleteMessage, 1); if (fullScreen && !SetFullScreen(fullScreen, res, false)) { return false; } XMapRaised(m_x11Display, (Window) m_nativeWindow); #endif #ifdef _WIN32 m_nativeWindow = m_hWnd; DEVMODE dm; ZeroMemory(&dm, sizeof(dm)); dm.dmSize = sizeof(dm); EnumDisplaySettingsEx(NULL, ENUM_CURRENT_SETTINGS, &dm, 0); m_nLeft = (dm.dmPelsWidth / 2) - (m_nWidth / 2); m_nTop = (dm.dmPelsHeight / 2) - (m_nHeight / 2); RECT rc; rc.left = m_nLeft; rc.top = m_nTop; rc.right = rc.left + m_nWidth; rc.bottom = rc.top + m_nHeight; AdjustWindowRect( &rc, WS_OVERLAPPEDWINDOW, false ); SetWindowPos(m_hWnd, 0, rc.left, rc.top, 0, 0, SWP_NOSIZE); #endif #if defined(HAS_GDL) m_nativeWindow = (NativeWindowType)GDL_GRAPHICS_PLANE; #endif m_surface = eglCreateWindowSurface(m_display, m_config, m_nativeWindow, attribList); if (!m_surface) { CLog::Log(LOGERROR, "EGL couldn't create window"); return false; } #ifdef CANMORE eglStatus = eglBindAPI(EGL_OPENGL_ES_API); if (!eglStatus) { CLog::Log(LOGERROR, "EGL failed to bind API"); return false; } #endif EGLint contextAttrs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE }; // Create an EGL context //CLog::Log(LOGDEBUG, "eglCreateContext"); m_context = eglCreateContext(m_display, m_config, NULL, contextAttrs); if (!m_context) { CLog::Log(LOGERROR, "EGL couldn't create context"); return false; } // Make the context and surface current for rendering eglStatus = eglMakeCurrent(m_display, m_surface, m_surface, m_context); if (!eglStatus) { CLog::Log(LOGERROR, "EGL couldn't make context/surface current"); return false; } free(configList); eglSwapInterval(m_display, 0); m_bWindowCreated = true; CLog::Log(LOGINFO, "Window creation complete"); return true; }