mirror of
https://github.com/Almamu/linux-wallpaperengine.git
synced 2025-09-14 13:56:48 +08:00
Working CEF
This commit is contained in:
parent
0b72eebacc
commit
39d34440d8
@ -32,12 +32,12 @@ find_package(FFMPEG REQUIRED)
|
|||||||
find_package(FreeImage REQUIRED)
|
find_package(FreeImage REQUIRED)
|
||||||
find_package(PulseAudio REQUIRED)
|
find_package(PulseAudio REQUIRED)
|
||||||
|
|
||||||
set(CEF_ROOT "/home/kermit/Projects/fun/linux-wallpaperengine/OffScreenCEF/thirdparty/cef_binary")
|
set(CEF_ROOT "/home/kermit/Projects/fun/linux-wallpaperengine/OffScreenCEF/thirdparty/cef_binary/")
|
||||||
find_package(CEF REQUIRED)
|
find_package(CEF REQUIRED)
|
||||||
|
|
||||||
set(
|
set(
|
||||||
CMAKE_RUNTIME_OUTPUT_DIRECTORY
|
CMAKE_RUNTIME_OUTPUT_DIRECTORY
|
||||||
${CMAKE_HOME_DIRECTORY}/bin
|
${CMAKE_HOME_DIRECTORY}/build
|
||||||
)
|
)
|
||||||
|
|
||||||
set(
|
set(
|
||||||
@ -47,7 +47,7 @@ set(
|
|||||||
|
|
||||||
set(
|
set(
|
||||||
TARGET_OUTPUT_DIRECTORY
|
TARGET_OUTPUT_DIRECTORY
|
||||||
${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/$<CONFIGURATION>
|
${CMAKE_HOME_DIRECTORY}/build
|
||||||
)
|
)
|
||||||
|
|
||||||
add_subdirectory(${CEF_LIBCEF_DLL_WRAPPER_PATH} libcef_dll_wrapper)
|
add_subdirectory(${CEF_LIBCEF_DLL_WRAPPER_PATH} libcef_dll_wrapper)
|
||||||
@ -63,8 +63,7 @@ include_directories(
|
|||||||
${FREEIMAGE_INCLUDE_DIR}
|
${FREEIMAGE_INCLUDE_DIR}
|
||||||
${PULSEAUDIO_INCLUDE_DIR}
|
${PULSEAUDIO_INCLUDE_DIR}
|
||||||
src
|
src
|
||||||
# /home/kermit/Projects/fun/linux-wallpaperengine/src/WallpaperEngine/Render/cefsimple_opengl
|
/home/kermit/Projects/fun/linux-wallpaperengine/OffScreenCEF/thirdparty/cef_binary
|
||||||
/home/kermit/Projects/fun/linux-wallpaperengine/cef-project/third_party/cef/cef_binary_106.0.26+ge105400+chromium-106.0.5249.91_linux64
|
|
||||||
${CMAKE_SOURCE_DIR}
|
${CMAKE_SOURCE_DIR}
|
||||||
include)
|
include)
|
||||||
|
|
||||||
@ -75,20 +74,19 @@ set_target_properties(ceflib
|
|||||||
# PROPERTIES IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/libcef.so)
|
# PROPERTIES IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/libcef.so)
|
||||||
PROPERTIES IMPORTED_LOCATION ${TARGET_OUTPUT_DIRECTORY}/libcef.so)
|
PROPERTIES IMPORTED_LOCATION ${TARGET_OUTPUT_DIRECTORY}/libcef.so)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
ADD_LOGICAL_TARGET("libcef_lib" "${CEF_LIB_DEBUG}" "${CEF_LIB_RELEASE}")
|
ADD_LOGICAL_TARGET("libcef_lib" "${CEF_LIB_DEBUG}" "${CEF_LIB_RELEASE}")
|
||||||
SET_CEF_TARGET_OUT_DIR()
|
# SET_CEF_TARGET_OUT_DIR()
|
||||||
include_directories(${_CEF_ROOT})
|
include_directories(${_CEF_ROOT})
|
||||||
message(CEF_ROOT="${_CEF_ROOT}")
|
message(CEF_ROOT="${_CEF_ROOT}")
|
||||||
message(CEF_ROOT="${CMAKE_SOURCE_DIR}")
|
|
||||||
|
|
||||||
# target_link_libraries(linux-wallpaperengine PUBLIC ceflib)
|
# target_link_libraries(linux-wallpaperengine PUBLIC ceflib)
|
||||||
# SET_LIBRARY_TARGET_PROPERTIES(linux-wallpaperengine)
|
# SET_LIBRARY_TARGET_PROPERTIES(linux-wallpaperengine)
|
||||||
message(PROJECT_SOURCE_DIR="${CMAKE_SOURCE_DIR}")
|
|
||||||
|
|
||||||
target_include_directories(ceflib
|
target_include_directories(ceflib
|
||||||
INTERFACE "/home/kermit/Projects/fun/linux-wallpaperengine/cef-project/third_party/cef/cef_binary_106.0.26+ge105400+chromium-106.0.5249.91_linux64/include")
|
INTERFACE "/home/kermit/Projects/fun/linux-wallpaperengine/cef-project/third_party/cef/cef_binary_106.0.26+ge105400+chromium-106.0.5249.91_linux64/include")
|
||||||
|
|
||||||
|
|
||||||
# target_link_libraries(linux-wallpaperengine "libcef" ${CEF_STANDARD_LIBS})
|
# target_link_libraries(linux-wallpaperengine "libcef" ${CEF_STANDARD_LIBS})
|
||||||
|
|
||||||
|
|
||||||
@ -246,15 +244,6 @@ add_executable(
|
|||||||
src/WallpaperEngine/Render/Helpers/CContextAware.cpp
|
src/WallpaperEngine/Render/Helpers/CContextAware.cpp
|
||||||
src/WallpaperEngine/Render/Helpers/CContextAware.h
|
src/WallpaperEngine/Render/Helpers/CContextAware.h
|
||||||
|
|
||||||
# src/WallpaperEngine/Render/cefsimple_opengl/CEFGLWindow.hpp
|
|
||||||
# src/WallpaperEngine/Render/cefsimple_opengl/CEFGLWindow.cpp
|
|
||||||
# src/WallpaperEngine/Render/cefsimple_opengl/GLWindow.hpp
|
|
||||||
# src/WallpaperEngine/Render/cefsimple_opengl/GLWindow.cpp
|
|
||||||
# src/WallpaperEngine/Render/cefsimple_opengl/BrowserView.hpp
|
|
||||||
# src/WallpaperEngine/Render/cefsimple_opengl/BrowserView.cpp
|
|
||||||
# src/WallpaperEngine/Render/cefsimple_opengl/GLCore.hpp
|
|
||||||
# src/WallpaperEngine/Render/cefsimple_opengl/GLCore.cpp
|
|
||||||
|
|
||||||
src/WallpaperEngine/Render/CWallpaper.h
|
src/WallpaperEngine/Render/CWallpaper.h
|
||||||
src/WallpaperEngine/Render/CWallpaper.cpp
|
src/WallpaperEngine/Render/CWallpaper.cpp
|
||||||
src/WallpaperEngine/Render/CWallpaperState.h
|
src/WallpaperEngine/Render/CWallpaperState.h
|
||||||
@ -385,6 +374,12 @@ add_executable(
|
|||||||
${WAYLAND_SOURCES}
|
${WAYLAND_SOURCES}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
COPY_FILES(linux-wallpaperengine "${CEF_BINARY_FILES}" "${CEF_BINARY_DIR}" "${TARGET_OUTPUT_DIRECTORY}")
|
||||||
|
COPY_FILES(linux-wallpaperengine "${CEF_RESOURCE_FILES}" "${CEF_RESOURCE_DIR}" "${TARGET_OUTPUT_DIRECTORY}")
|
||||||
|
|
||||||
|
message("${CEF_RESOURCE_FILES}")
|
||||||
|
message("${TARGET_OUTPUT_DIRECTORY}")
|
||||||
|
|
||||||
SET_EXECUTABLE_TARGET_PROPERTIES(linux-wallpaperengine)
|
SET_EXECUTABLE_TARGET_PROPERTIES(linux-wallpaperengine)
|
||||||
add_dependencies(linux-wallpaperengine libcef_dll_wrapper)
|
add_dependencies(linux-wallpaperengine libcef_dll_wrapper)
|
||||||
target_link_libraries (linux-wallpaperengine PUBLIC
|
target_link_libraries (linux-wallpaperengine PUBLIC
|
||||||
@ -404,24 +399,6 @@ target_link_libraries (linux-wallpaperengine PUBLIC
|
|||||||
${PULSEAUDIO_LIBRARY}
|
${PULSEAUDIO_LIBRARY}
|
||||||
glfw)
|
glfw)
|
||||||
|
|
||||||
COPY_FILES(linux-wallpaperengine "${CEF_BINARY_FILES}" "${CEF_BINARY_DIR}" "${TARGET_OUTPUT_DIRECTORY}")
|
|
||||||
COPY_FILES(linux-wallpaperengine "${CEF_RESOURCE_FILES}" "${CEF_RESOURCE_DIR}" "${TARGET_OUTPUT_DIRECTORY}")
|
|
||||||
|
|
||||||
# target_link_libraries(linux-wallpaperengine PUBLIC
|
|
||||||
# ${X11_LIBRARIES}
|
|
||||||
# ${Xrandr_LIBRARIES}
|
|
||||||
# ${X11_Xxf86vm_LIB}
|
|
||||||
# ${OPENGL_LIBRARIES}
|
|
||||||
# ${GLEW_LIBRARIES}
|
|
||||||
# ${GLUT_LIBRARIES}
|
|
||||||
# ${ZLIB_LIBRARIES}
|
|
||||||
# ${LZ4_LIBRARY}
|
|
||||||
# ${SDL2_LIBRARIES}
|
|
||||||
# ${FFMPEG_LIBRARIES}
|
|
||||||
# ${FREEIMAGE_LIBRARIES}
|
|
||||||
# ${MPV_LIBRARY}
|
|
||||||
# ${PULSEAUDIO_LIBRARY}
|
|
||||||
# glfw)
|
|
||||||
|
|
||||||
if (WAYLAND_SUPPORT_FOUND)
|
if (WAYLAND_SUPPORT_FOUND)
|
||||||
target_link_libraries(linux-wallpaperengine PUBLIC
|
target_link_libraries(linux-wallpaperengine PUBLIC
|
||||||
|
79
main.cpp
79
main.cpp
@ -3,12 +3,19 @@
|
|||||||
|
|
||||||
#include "WallpaperEngine/Application/CApplicationContext.h"
|
#include "WallpaperEngine/Application/CApplicationContext.h"
|
||||||
#include "WallpaperEngine/Application/CWallpaperApplication.h"
|
#include "WallpaperEngine/Application/CWallpaperApplication.h"
|
||||||
|
#include "WallpaperEngine/Core/CWeb.h"
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
WallpaperEngine::Application::CWallpaperApplication* appPointer;
|
WallpaperEngine::Application::CWallpaperApplication* appPointer;
|
||||||
|
|
||||||
void signalhandler(int sig)
|
void signalhandler(int sig)
|
||||||
{
|
{
|
||||||
|
sLog.debug("Hello");
|
||||||
|
if(g_CEFused){
|
||||||
|
sLog.debug("Shutting down CEF");
|
||||||
|
CefShutdown();
|
||||||
|
}
|
||||||
|
|
||||||
if (appPointer == nullptr)
|
if (appPointer == nullptr)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -21,11 +28,69 @@ void initLogging ()
|
|||||||
sLog.addError (new std::ostream (std::cerr.rdbuf ()));
|
sLog.addError (new std::ostream (std::cerr.rdbuf ()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void CEFsetUp(int argc, char** argv)
|
||||||
|
{
|
||||||
|
// This function should be called from the application entry point function to
|
||||||
|
// execute a secondary process. It can be used to run secondary processes from
|
||||||
|
// the browser client executable (default behavior) or from a separate
|
||||||
|
// executable specified by the CefSettings.browser_subprocess_path value. If
|
||||||
|
// called for the browser process (identified by no "type" command-line value)
|
||||||
|
// it will return immediately with a value of -1. If called for a recognized
|
||||||
|
// secondary process it will block until the process should exit and then return
|
||||||
|
// the process exit code. The |application| parameter may be empty. The
|
||||||
|
// |windows_sandbox_info| parameter is only used on Windows and may be NULL (see
|
||||||
|
// cef_sandbox_win.h for details).
|
||||||
|
|
||||||
|
CefMainArgs args(argc, argv);
|
||||||
|
|
||||||
|
int exit_code = CefExecuteProcess(args, nullptr, nullptr);//Spawned processes will terminate here(see CefIninitilize below). Maybe implementing settings.browser_subprocess_path will allow it to work not in main function.
|
||||||
|
if (exit_code >= 0)
|
||||||
|
{
|
||||||
|
// Sub proccess has endend, so exit
|
||||||
|
exit(exit_code);
|
||||||
|
}
|
||||||
|
else if (exit_code == -1)
|
||||||
|
{
|
||||||
|
// If called for the browser process (identified by no "type" command-line value)
|
||||||
|
// it will return immediately with a value of -1
|
||||||
|
}
|
||||||
|
|
||||||
|
// Configurate Chromium
|
||||||
|
CefSettings settings;
|
||||||
|
//CefString(&settings.locales_dir_path) = "OffScreenCEF/godot/locales";
|
||||||
|
//CefString(&settings.resources_dir_path) = "OffScreenCEF/godot/";
|
||||||
|
//CefString(&settings.framework_dir_path) = "OffScreenCEF/godot/";
|
||||||
|
//CefString(&settings.cache_path) = "OffScreenCEF/godot/";
|
||||||
|
// CefString(&settings.browser_subprocess_path) = "path/to/client"
|
||||||
|
settings.windowless_rendering_enabled = true;
|
||||||
|
#if defined(CEF_NO_SANDBOX)
|
||||||
|
settings.no_sandbox = true;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
bool result = CefInitialize(args, settings, nullptr, nullptr); //Spawn 2 new processes; Can be moved to Core::CWeb
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
std::cerr << "CefInitialize: failed" << std::endl;
|
||||||
|
exit(-2);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
bool g_CEFused=false;//Will be set to true if wallpaper has "web" type
|
||||||
int main (int argc, char* argv[])
|
int main (int argc, char* argv[])
|
||||||
{
|
{
|
||||||
initLogging ();
|
//START of CEF init block(it will run 3 times)
|
||||||
|
char** argv2 = new char*[argc]; //Cef modify argv on CefInit, copy it before that
|
||||||
|
|
||||||
WallpaperEngine::Application::CApplicationContext appContext (argc, argv);
|
for(int i=0; i<argc; ++i)
|
||||||
|
{
|
||||||
|
argv2[i] = new char[strlen(argv[i])+1];
|
||||||
|
strcpy(argv2[i],argv[i]);
|
||||||
|
}
|
||||||
|
CEFsetUp(argc,argv);//Cef will launch new process with main(argc,argv) twice. If we won't pass argc and argv from main, we will create fork bomb and system will freeze until reboot.
|
||||||
|
//END of CEF init block
|
||||||
|
initLogging ();
|
||||||
|
WallpaperEngine::Application::CApplicationContext appContext (argc, argv2);
|
||||||
WallpaperEngine::Application::CWallpaperApplication app (appContext);
|
WallpaperEngine::Application::CWallpaperApplication app (appContext);
|
||||||
|
|
||||||
// halt if the list-properties option was specified
|
// halt if the list-properties option was specified
|
||||||
@ -38,10 +103,18 @@ int main (int argc, char* argv[])
|
|||||||
std::signal (SIGINT, signalhandler);
|
std::signal (SIGINT, signalhandler);
|
||||||
std::signal (SIGTERM, signalhandler);
|
std::signal (SIGTERM, signalhandler);
|
||||||
|
|
||||||
|
if(!g_CEFused){
|
||||||
|
sLog.debug("No web wallpapers, shutting down CEF");
|
||||||
|
CefShutdown();
|
||||||
|
}
|
||||||
// show the wallpaper application
|
// show the wallpaper application
|
||||||
app.show ();
|
app.show ();
|
||||||
|
|
||||||
appPointer = nullptr;
|
if(g_CEFused){
|
||||||
|
sLog.debug("Shutting down CEF");
|
||||||
|
CefShutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
appPointer = nullptr;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
@ -5,6 +5,7 @@
|
|||||||
#include "CProject.h"
|
#include "CProject.h"
|
||||||
#include "CScene.h"
|
#include "CScene.h"
|
||||||
#include "CVideo.h"
|
#include "CVideo.h"
|
||||||
|
#include "CWeb.h"
|
||||||
|
|
||||||
using namespace WallpaperEngine::Core;
|
using namespace WallpaperEngine::Core;
|
||||||
using namespace WallpaperEngine::Assets;
|
using namespace WallpaperEngine::Assets;
|
||||||
@ -18,41 +19,45 @@ CProject::CProject (std::string title, std::string type, CContainer* container)
|
|||||||
CProject* CProject::fromFile (const std::string& filename, CContainer* container) {
|
CProject* CProject::fromFile (const std::string& filename, CContainer* container) {
|
||||||
json content = json::parse (WallpaperEngine::FileSystem::loadFullFile (filename, container));
|
json content = json::parse (WallpaperEngine::FileSystem::loadFullFile (filename, container));
|
||||||
|
|
||||||
const std::string title = *jsonFindRequired (content, "title", "Project title missing");
|
std::string dependency = jsonFindDefault<std::string> (content, "dependency", "No dependency");
|
||||||
std::string type = *jsonFindRequired (content, "type", "Project type missing");
|
if(dependency=="No dependency"){
|
||||||
const std::string file = *jsonFindRequired (content, "file", "Project's main file missing");
|
std::string title = *jsonFindRequired (content, "title", "Project title missing");
|
||||||
const auto general = content.find ("general");
|
std::string type = *jsonFindRequired (content, "type", "Project type missing");
|
||||||
CWallpaper* wallpaper;
|
std::string file = *jsonFindRequired (content, "file", "Project's main file missing");
|
||||||
|
auto general = content.find ("general");
|
||||||
|
CWallpaper* wallpaper;
|
||||||
|
|
||||||
std::transform (type.begin (), type.end (), type.begin (), tolower);
|
std::transform (type.begin (), type.end (), type.begin (), tolower);
|
||||||
|
|
||||||
CProject* project = new CProject (title, type, container);
|
CProject* project = new CProject (title, type, container);
|
||||||
|
|
||||||
if (type == "scene")
|
if (type == "scene")
|
||||||
wallpaper = CScene::fromFile (file, *project, container);
|
wallpaper = CScene::fromFile (file, *project, container);
|
||||||
else if (type == "video")
|
else if (type == "video")
|
||||||
wallpaper = new CVideo (file, *project);
|
wallpaper = new CVideo (file.c_str (), *project);
|
||||||
else if (type == "web")
|
else if (type == "web")
|
||||||
sLog.exception ("Web wallpapers are not supported yet");
|
wallpaper = new CWeb (file.c_str (), *project);
|
||||||
else
|
else
|
||||||
sLog.exception ("Unsupported wallpaper type: ", type);
|
sLog.exception ("Unsupported wallpaper type: ", type);
|
||||||
|
|
||||||
project->setWallpaper (wallpaper);
|
project->setWallpaper (wallpaper);
|
||||||
|
|
||||||
if (general != content.end ()) {
|
if (general != content.end ()) {
|
||||||
const auto properties = general->find ("properties");
|
const auto properties = general->find ("properties");
|
||||||
|
|
||||||
if (properties != general->end ()) {
|
if (properties != general-> end ()) {
|
||||||
for (const auto& cur : properties->items ()) {
|
for (const auto& cur : properties->items ()) {
|
||||||
Projects::CProperty* property = Projects::CProperty::fromJSON (cur.value (), cur.key ());
|
Projects::CProperty* property = Projects::CProperty::fromJSON (cur.value (), cur.key ());
|
||||||
|
if (property != nullptr)
|
||||||
if (property != nullptr)
|
project->insertProperty (property);
|
||||||
project->insertProperty (property);
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return project;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
sLog.exception("Project have dependency. They are not supported, quiting");
|
||||||
}
|
}
|
||||||
|
|
||||||
return project;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CProject::setWallpaper (CWallpaper* wallpaper) {
|
void CProject::setWallpaper (CWallpaper* wallpaper) {
|
||||||
|
71
src/WallpaperEngine/Core/CWeb.cpp
Normal file
71
src/WallpaperEngine/Core/CWeb.cpp
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
#include "CWeb.h"
|
||||||
|
|
||||||
|
#include <utility>
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
|
static void CEFsetUp(int argc, char** argv)
|
||||||
|
{
|
||||||
|
// This function should be called from the application entry point function to
|
||||||
|
// execute a secondary process. It can be used to run secondary processes from
|
||||||
|
// the browser client executable (default behavior) or from a separate
|
||||||
|
// executable specified by the CefSettings.browser_subprocess_path value. If
|
||||||
|
// called for the browser process (identified by no "type" command-line value)
|
||||||
|
// it will return immediately with a value of -1. If called for a recognized
|
||||||
|
// secondary process it will block until the process should exit and then return
|
||||||
|
// the process exit code. The |application| parameter may be empty. The
|
||||||
|
// |windows_sandbox_info| parameter is only used on Windows and may be NULL (see
|
||||||
|
// cef_sandbox_win.h for details).
|
||||||
|
CefMainArgs args(argc,argv);
|
||||||
|
int exit_code = CefExecuteProcess(args, nullptr, nullptr);
|
||||||
|
if (exit_code >= 0)
|
||||||
|
{
|
||||||
|
sLog.debug("CEF sub proccess has endend");
|
||||||
|
// Sub proccess has endend, so exit
|
||||||
|
exit(exit_code);
|
||||||
|
}
|
||||||
|
else if (exit_code == -1)
|
||||||
|
{
|
||||||
|
// If called for the browser process (identified by no "type" command-line value)
|
||||||
|
// it will return immediately with a value of -1
|
||||||
|
}
|
||||||
|
|
||||||
|
// Configurate Chromium
|
||||||
|
CefSettings settings;
|
||||||
|
//CefString(&settings.locales_dir_path) = "OffScreenCEF/godot/locales";
|
||||||
|
//CefString(&settings.resources_dir_path) = "OffScreenCEF/godot/";
|
||||||
|
//CefString(&settings.framework_dir_path) = "OffScreenCEF/godot/";
|
||||||
|
//CefString(&settings.cache_path) = "OffScreenCEF/godot/";
|
||||||
|
settings.windowless_rendering_enabled = true;
|
||||||
|
#if defined(CEF_NO_SANDBOX)
|
||||||
|
settings.no_sandbox = true;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
bool result = CefInitialize(args, settings, nullptr, nullptr);
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
sLog.error("CefInitialize: failed");
|
||||||
|
exit(-2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
using namespace WallpaperEngine::Core;
|
||||||
|
|
||||||
|
const std::string& CWeb::getFilename ()
|
||||||
|
{
|
||||||
|
return this->m_filename;
|
||||||
|
}
|
||||||
|
|
||||||
|
CWeb::CWeb (std::string filename, CProject& project) :
|
||||||
|
CWallpaper (Type, project),
|
||||||
|
m_filename (std::move(filename))
|
||||||
|
{
|
||||||
|
if(!g_CEFused) {
|
||||||
|
sLog.debug("Setting up CEF");
|
||||||
|
// char** argv = new char*("linux-wallpaper\n");
|
||||||
|
// CEFsetUp(1, argv);
|
||||||
|
// delete argv;
|
||||||
|
g_CEFused=true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string CWeb::Type = "web";
|
37
src/WallpaperEngine/Core/CWeb.h
Normal file
37
src/WallpaperEngine/Core/CWeb.h
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Core.h"
|
||||||
|
#include "CWallpaper.h"
|
||||||
|
|
||||||
|
// Chromium Embedded Framework
|
||||||
|
#include "include/cef_render_handler.h"
|
||||||
|
#include "include/cef_client.h"
|
||||||
|
#include "include/cef_app.h"
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#include <libavcodec/avcodec.h>
|
||||||
|
#include <libavformat/avformat.h>
|
||||||
|
#include <libavutil/imgutils.h>
|
||||||
|
#include <libswscale/swscale.h>
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace WallpaperEngine::Core
|
||||||
|
{
|
||||||
|
class CWeb : public CWallpaper
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit CWeb (std::string filename, CProject& project);
|
||||||
|
|
||||||
|
const std::string& getFilename ();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
friend class CWallpaper;
|
||||||
|
|
||||||
|
const std::string m_filename;
|
||||||
|
|
||||||
|
static const std::string Type;
|
||||||
|
|
||||||
|
private:
|
||||||
|
};
|
||||||
|
}
|
@ -2,11 +2,12 @@
|
|||||||
#include "CScene.h"
|
#include "CScene.h"
|
||||||
#include "CVideo.h"
|
#include "CVideo.h"
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
#include "CWeb.h"
|
||||||
|
|
||||||
#include <glm/glm.hpp>
|
#include <glm/glm.hpp>
|
||||||
#include <glm/gtc/type_ptr.hpp>
|
#include <glm/gtc/type_ptr.hpp>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include "Drivers/CX11OpenGLDriver.h"
|
|
||||||
using namespace WallpaperEngine::Render;
|
using namespace WallpaperEngine::Render;
|
||||||
|
|
||||||
CWallpaper::CWallpaper (Core::CWallpaper* wallpaperData, std::string type, CRenderContext& context,
|
CWallpaper::CWallpaper (Core::CWallpaper* wallpaperData, std::string type, CRenderContext& context,
|
||||||
@ -25,9 +26,7 @@ CWallpaper::CWallpaper (Core::CWallpaper* wallpaperData, std::string type, CRend
|
|||||||
m_vaoBuffer (GL_NONE),
|
m_vaoBuffer (GL_NONE),
|
||||||
m_audioContext (audioContext),
|
m_audioContext (audioContext),
|
||||||
m_state (scalingMode),
|
m_state (scalingMode),
|
||||||
cef_window(1920,1080, "test title", reinterpret_cast<Drivers::CX11OpenGLDriver*>(const_cast<Drivers::CVideoDriver*>(&context.getDriver()))->getWindow())
|
|
||||||
{
|
{
|
||||||
cef_window.setup();
|
|
||||||
// generate the VAO to stop opengl from complaining
|
// generate the VAO to stop opengl from complaining
|
||||||
glGenVertexArrays (1, &this->m_vaoBuffer);
|
glGenVertexArrays (1, &this->m_vaoBuffer);
|
||||||
glBindVertexArray (this->m_vaoBuffer);
|
glBindVertexArray (this->m_vaoBuffer);
|
||||||
@ -197,7 +196,105 @@ void CWallpaper::updateUVs (const glm::ivec4& viewport, const bool vflip) {
|
|||||||
|
|
||||||
void CWallpaper::render (glm::ivec4 viewport, bool vflip) {
|
void CWallpaper::render (glm::ivec4 viewport, bool vflip) {
|
||||||
this->renderFrame (viewport);
|
this->renderFrame (viewport);
|
||||||
cef_window.update();
|
|
||||||
|
uint32_t projectionWidth = this->getWidth ();
|
||||||
|
uint32_t projectionHeight = this->getHeight ();
|
||||||
|
|
||||||
|
float ustart = 0.0f;
|
||||||
|
float uend = 0.0f;
|
||||||
|
float vstart = 0.0f;
|
||||||
|
float vend = 0.0f;
|
||||||
|
|
||||||
|
if (
|
||||||
|
(viewport.w > viewport.z && projectionWidth >= projectionHeight) ||
|
||||||
|
(viewport.z > viewport.w && projectionHeight > projectionWidth)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (vflip)
|
||||||
|
{
|
||||||
|
vstart = 0.0f;
|
||||||
|
vend = 1.0f;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vstart = 1.0f;
|
||||||
|
vend = 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
int newWidth = viewport.w / (float) projectionHeight * projectionWidth;
|
||||||
|
float newCenter = newWidth / 2.0f;
|
||||||
|
float viewportCenter = viewport.z / 2.0;
|
||||||
|
|
||||||
|
float left = newCenter - viewportCenter;
|
||||||
|
float right = newCenter + viewportCenter;
|
||||||
|
|
||||||
|
ustart = left / newWidth;
|
||||||
|
uend = right / newWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
(viewport.z > viewport.w && projectionWidth >= projectionHeight) ||
|
||||||
|
(viewport.w > viewport.z && projectionHeight > projectionWidth)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ustart = 0.0f;
|
||||||
|
uend = 1.0f;
|
||||||
|
|
||||||
|
int newHeight = viewport.z / (float) projectionWidth * projectionHeight;
|
||||||
|
float newCenter = newHeight / 2.0f;
|
||||||
|
float viewportCenter = viewport.w / 2.0;
|
||||||
|
|
||||||
|
float down = newCenter - viewportCenter;
|
||||||
|
float up = newCenter + viewportCenter;
|
||||||
|
|
||||||
|
if (vflip)
|
||||||
|
{
|
||||||
|
vstart = down / newHeight;
|
||||||
|
vend = up / newHeight;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vstart = up / newHeight;
|
||||||
|
vend = down / newHeight;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GLfloat texCoords [] = {
|
||||||
|
ustart, vstart,
|
||||||
|
uend, vstart,
|
||||||
|
ustart, vend,
|
||||||
|
ustart, vend,
|
||||||
|
uend, vstart,
|
||||||
|
uend, vend,
|
||||||
|
};
|
||||||
|
|
||||||
|
glViewport (viewport.x, viewport.y, viewport.z, viewport.w);
|
||||||
|
|
||||||
|
glBindFramebuffer (GL_FRAMEBUFFER, this->m_destFramebuffer);
|
||||||
|
|
||||||
|
glBindVertexArray (this->m_vaoBuffer);
|
||||||
|
|
||||||
|
glDisable (GL_BLEND);
|
||||||
|
glDisable (GL_DEPTH_TEST);
|
||||||
|
// do not use any shader
|
||||||
|
glUseProgram (this->m_shader);
|
||||||
|
// activate scene texture
|
||||||
|
glActiveTexture (GL_TEXTURE0);
|
||||||
|
glBindTexture (GL_TEXTURE_2D, this->getWallpaperTexture ());
|
||||||
|
// set uniforms and attribs
|
||||||
|
glEnableVertexAttribArray (this->a_TexCoord);
|
||||||
|
glBindBuffer (GL_ARRAY_BUFFER, this->m_texCoordBuffer);
|
||||||
|
glBufferData (GL_ARRAY_BUFFER, sizeof (texCoords), texCoords, GL_STATIC_DRAW);
|
||||||
|
glVertexAttribPointer (this->a_TexCoord, 2, GL_FLOAT, GL_FALSE, 0, nullptr);
|
||||||
|
|
||||||
|
glEnableVertexAttribArray (this->a_Position);
|
||||||
|
glBindBuffer (GL_ARRAY_BUFFER, this->m_positionBuffer);
|
||||||
|
glVertexAttribPointer (this->a_Position, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
|
||||||
|
|
||||||
|
glUniform1i (this->g_Texture0, 0);
|
||||||
|
// write the framebuffer as is to the screen
|
||||||
|
glBindBuffer (GL_ARRAY_BUFFER, this->m_texCoordBuffer);
|
||||||
|
glDrawArrays (GL_TRIANGLES, 0, 6);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CWallpaper::setupFramebuffers () {
|
void CWallpaper::setupFramebuffers () {
|
||||||
@ -254,6 +351,8 @@ CWallpaper* CWallpaper::fromWallpaper (Core::CWallpaper* wallpaper, CRenderConte
|
|||||||
return new WallpaperEngine::Render::CScene (wallpaper->as<Core::CScene> (), context, audioContext, scalingMode);
|
return new WallpaperEngine::Render::CScene (wallpaper->as<Core::CScene> (), context, audioContext, scalingMode);
|
||||||
if (wallpaper->is<Core::CVideo> ())
|
if (wallpaper->is<Core::CVideo> ())
|
||||||
return new WallpaperEngine::Render::CVideo (wallpaper->as<Core::CVideo> (), context, audioContext, scalingMode);
|
return new WallpaperEngine::Render::CVideo (wallpaper->as<Core::CVideo> (), context, audioContext, scalingMode);
|
||||||
|
else if (wallpaper->is <Core::CWeb> ())
|
||||||
sLog.exception ("Unsupported wallpaper type");
|
return new WallpaperEngine::Render::CWeb (wallpaper->as <Core::CWeb> (), context, audioContext);
|
||||||
|
else
|
||||||
|
sLog.exception ("Unsupported wallpaper type");
|
||||||
}
|
}
|
@ -185,6 +185,5 @@ class CWallpaper : public Helpers::CContextAware {
|
|||||||
CAudioContext& m_audioContext;
|
CAudioContext& m_audioContext;
|
||||||
/** Current Wallpaper state */
|
/** Current Wallpaper state */
|
||||||
CWallpaperState m_state;
|
CWallpaperState m_state;
|
||||||
CEFGLWindow cef_window;
|
|
||||||
};
|
};
|
||||||
} // namespace WallpaperEngine::Render
|
} // namespace WallpaperEngine::Render
|
||||||
|
@ -1,249 +1,228 @@
|
|||||||
// This code is a modification of the original projects that can be found at
|
// This code is a modification of the original projects that can be found at
|
||||||
// https://github.com/if1live/cef-gl-example
|
// https://github.com/if1live/cef-gl-example
|
||||||
// https://github.com/andmcgregor/cefgui
|
// https://github.com/andmcgregor/cefgui
|
||||||
|
#include "CWeb.h"
|
||||||
|
|
||||||
#include "BrowserView.hpp"
|
using namespace WallpaperEngine::Render;
|
||||||
#include "GLCore.hpp"
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
CWeb::CWeb (Core::CWeb* web, CRenderContext& context, CAudioContext& audioContext) :
|
||||||
BrowserView::RenderHandler::RenderHandler(glm::vec4 const& viewport)
|
CWallpaper (web, Type, context, audioContext),
|
||||||
: m_viewport(viewport)
|
m_width (context.getOutput ().getFullWidth ()),
|
||||||
{}
|
m_height (context.getOutput ().getFullHeight ()),
|
||||||
|
m_browser(),
|
||||||
//------------------------------------------------------------------------------
|
m_client()
|
||||||
BrowserView::RenderHandler::~RenderHandler()
|
|
||||||
{
|
{
|
||||||
// Free GPU memory
|
// setup framebuffers
|
||||||
GLCore::deleteProgram(m_prog);
|
this->setupFramebuffers();
|
||||||
glDeleteBuffers(1, &m_vbo);
|
|
||||||
glDeleteVertexArrays(1, &m_vao);
|
|
||||||
}
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
bool BrowserView::RenderHandler::init()
|
|
||||||
{
|
|
||||||
// Dummy texture data
|
|
||||||
const unsigned char data[] = {
|
|
||||||
255, 0, 0, 255,
|
|
||||||
0, 255, 0, 255,
|
|
||||||
0, 0, 255, 255,
|
|
||||||
255, 255, 255, 255,
|
|
||||||
};
|
|
||||||
|
|
||||||
// Compile vertex and fragment shaders
|
|
||||||
m_prog = GLCore::createShaderProgram("shaders/tex.vert", "shaders/tex.frag");
|
|
||||||
if (m_prog == 0)
|
|
||||||
{
|
|
||||||
std::cerr << "shader compile failed" << std::endl;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get locations of shader variables (attributes and uniforms)
|
|
||||||
m_pos_loc = GLCHECK(glGetAttribLocation(m_prog, "position"));
|
|
||||||
m_tex_loc = GLCHECK(glGetUniformLocation(m_prog, "tex"));
|
|
||||||
m_mvp_loc = GLCHECK(glGetUniformLocation(m_prog, "mvp"))
|
|
||||||
|
|
||||||
// Square vertices (texture positions are computed directly inside the shader)
|
|
||||||
float coords[] = {-1.0,-1.0,-1.0,1.0,1.0,-1.0,1.0,-1.0,-1.0,1.0,1.0,1.0};
|
|
||||||
|
|
||||||
// See https://learnopengl.com/Getting-started/Textures
|
|
||||||
GLCHECK(glGenVertexArrays(1, &m_vao));
|
|
||||||
GLCHECK(glBindVertexArray(m_vao));
|
|
||||||
GLCHECK(glGenBuffers(1, &m_vbo));
|
|
||||||
GLCHECK(glBindBuffer(GL_ARRAY_BUFFER, m_vbo));
|
|
||||||
GLCHECK(glBufferData(GL_ARRAY_BUFFER, sizeof(coords), coords, GL_STATIC_DRAW));
|
|
||||||
GLCHECK(glEnableVertexAttribArray(m_pos_loc));
|
|
||||||
GLCHECK(glVertexAttribPointer(m_pos_loc, 2, GL_FLOAT, GL_FALSE, 0, 0));
|
|
||||||
|
|
||||||
// GLCHECK(glGenTextures(1, &m_tex));
|
|
||||||
// GLCHECK(glBindTexture(GL_TEXTURE_2D, m_tex));
|
|
||||||
// GLCHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
|
|
||||||
// GLCHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
|
|
||||||
// GLCHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
|
|
||||||
// GLCHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
|
|
||||||
// GLCHECK(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, data));
|
|
||||||
// GLCHECK(glBindTexture(GL_TEXTURE_2D, 0));
|
|
||||||
|
|
||||||
GLCHECK(glBindBuffer(GL_ARRAY_BUFFER, 0));
|
|
||||||
GLCHECK(glBindVertexArray(0));
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
void BrowserView::RenderHandler::draw(glm::vec4 const& viewport, bool fixed)
|
|
||||||
{
|
|
||||||
// Where to paint on the OpenGL window
|
|
||||||
GLCHECK(glViewport(viewport[0],
|
|
||||||
viewport[1],
|
|
||||||
GLsizei(viewport[2] * m_width),
|
|
||||||
GLsizei(viewport[3] * m_height)));
|
|
||||||
|
|
||||||
// // Apply a rotation
|
|
||||||
glm::mat4 trans = glm::mat4(1.0f); // Identity matrix
|
|
||||||
// if (!fixed)
|
|
||||||
// {
|
|
||||||
// trans = glm::translate(trans, glm::vec3(0.5f, -0.5f, 0.0f));
|
|
||||||
// trans = glm::rotate(trans, (float)glfwGetTime() / 5.0f, glm::vec3(0.0f, 0.0f, 1.0f));
|
|
||||||
// }
|
|
||||||
|
|
||||||
// See https://learnopengl.com/Getting-started/Textures
|
|
||||||
GLCHECK(glUseProgram(m_prog));
|
|
||||||
GLCHECK(glBindVertexArray(m_vao));
|
|
||||||
|
|
||||||
GLCHECK(glUniformMatrix4fv(m_mvp_loc, 1, GL_FALSE, glm::value_ptr(trans)));
|
|
||||||
GLCHECK(glBindBuffer(GL_ARRAY_BUFFER, m_vbo));
|
|
||||||
GLCHECK(glActiveTexture(GL_TEXTURE0));
|
|
||||||
GLCHECK(glBindTexture(GL_TEXTURE_2D, m_tex));
|
|
||||||
GLCHECK(glDrawArrays(GL_TRIANGLES, 0, 6));
|
|
||||||
GLCHECK(glBindTexture(GL_TEXTURE_2D, 0));
|
|
||||||
GLCHECK(glBindBuffer(GL_ARRAY_BUFFER, 0));
|
|
||||||
|
|
||||||
GLCHECK(glBindVertexArray(0));
|
|
||||||
GLCHECK(glUseProgram(0));
|
|
||||||
}
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
void BrowserView::RenderHandler::reshape(int w, int h)
|
|
||||||
{
|
|
||||||
m_width = w;
|
|
||||||
m_height = h;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool BrowserView::viewport(float x, float y, float w, float h)
|
|
||||||
{
|
|
||||||
if (!(x >= 0.0f) && (x < 1.0f))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (!(x >= 0.0f) && (y < 1.0f))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (!(w > 0.0f) && (w <= 1.0f))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (!(h > 0.0f) && (h <= 1.0f))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (x + w > 1.0f)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (y + h > 1.0f)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
m_viewport[0] = x;
|
|
||||||
m_viewport[1] = y;
|
|
||||||
m_viewport[2] = w;
|
|
||||||
m_viewport[3] = h;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
void BrowserView::RenderHandler::GetViewRect(CefRefPtr<CefBrowser> browser, CefRect &rect)
|
|
||||||
{
|
|
||||||
rect = CefRect(m_viewport[0], m_viewport[1], m_viewport[2] * m_width, m_viewport[3] * m_height);
|
|
||||||
}
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
void BrowserView::RenderHandler::OnPaint(CefRefPtr<CefBrowser> browser, PaintElementType type,
|
|
||||||
const RectList &dirtyRects, const void *buffer,
|
|
||||||
int width, int height)
|
|
||||||
{
|
|
||||||
//std::cout << "BrowserView::RenderHandler::OnPaint" << std::endl;
|
|
||||||
GLCHECK(glActiveTexture(GL_TEXTURE0));
|
|
||||||
GLCHECK(glBindTexture(GL_TEXTURE_2D, m_tex));
|
|
||||||
GLCHECK(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_BGRA_EXT,
|
|
||||||
GL_UNSIGNED_BYTE, (unsigned char*)buffer));
|
|
||||||
GLCHECK(glBindTexture(GL_TEXTURE_2D, 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
BrowserView::BrowserView(const std::string &url)
|
|
||||||
: m_mouse_x(0), m_mouse_y(0), m_viewport(0.0f, 0.0f, 1.0f, 1.0f)
|
|
||||||
{
|
|
||||||
CefWindowInfo window_info;
|
CefWindowInfo window_info;
|
||||||
window_info.SetAsWindowless(0);
|
window_info.SetAsWindowless(0);
|
||||||
|
|
||||||
m_render_handler = new RenderHandler(m_viewport);
|
this->m_render_handler = new RenderHandler(this);
|
||||||
m_initialized = m_render_handler->init();
|
|
||||||
m_render_handler->reshape(128, 128); // initial size
|
|
||||||
|
|
||||||
CefBrowserSettings browserSettings;
|
CefBrowserSettings browserSettings;
|
||||||
browserSettings.windowless_frame_rate = 60; // 30 is default
|
//Documentaion says said that 60 fps is maximum value
|
||||||
|
browserSettings.windowless_frame_rate = std::max(60,context.getApp().getContext().settings.render.maximumFPS);
|
||||||
|
|
||||||
m_client = new BrowserClient(m_render_handler);
|
m_client = new BrowserClient(m_render_handler);
|
||||||
|
std::filesystem::path htmlpath = this->getWeb ()->getProject ().getContainer ()->resolveRealFile (this->getWeb ()->getFilename ());
|
||||||
|
//To open local file in browser URL must be "file:///path/to/file.html"
|
||||||
|
const std::string htmlURL = std::string("file:///") + htmlpath.c_str();
|
||||||
m_browser = CefBrowserHost::CreateBrowserSync(window_info, m_client.get(),
|
m_browser = CefBrowserHost::CreateBrowserSync(window_info, m_client.get(),
|
||||||
url, browserSettings,
|
htmlURL, browserSettings,
|
||||||
nullptr, nullptr);
|
nullptr, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
void CWeb::setSize (int64_t width, int64_t height)
|
||||||
BrowserView::~BrowserView()
|
|
||||||
{
|
{
|
||||||
CefDoMessageLoopWork();
|
this->m_width = width > 0 ? width : this->m_width;
|
||||||
m_browser->GetHost()->CloseBrowser(true);
|
this->m_height = height > 0 ? height : this->m_height;
|
||||||
|
|
||||||
m_browser = nullptr;
|
// do not refresh the texture if any of the sizes are invalid
|
||||||
m_client = nullptr;
|
if (this->m_width <= 0 || this->m_height <= 0)
|
||||||
}
|
return;
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
// reconfigure the texture
|
||||||
void BrowserView::load(const std::string &url)
|
glBindTexture (GL_TEXTURE_2D, this->getWallpaperTexture());
|
||||||
{
|
glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA8, this->getWidth(), this->getHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
|
||||||
assert(m_initialized);
|
|
||||||
m_browser->GetMainFrame()->LoadURL(url);
|
|
||||||
}
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
// Notify cef that it was resized(maybe it's not even needed)
|
||||||
void BrowserView::draw()
|
|
||||||
{
|
|
||||||
CefDoMessageLoopWork();
|
|
||||||
m_render_handler->draw(m_viewport, m_fixed);
|
|
||||||
}
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
void BrowserView::reshape(int w, int h)
|
|
||||||
{
|
|
||||||
m_render_handler->reshape(w, h);
|
|
||||||
GLCHECK(glViewport(m_viewport[0],
|
|
||||||
m_viewport[1],
|
|
||||||
GLsizei(m_viewport[2] * w),
|
|
||||||
GLsizei(m_viewport[3] * h)));
|
|
||||||
m_browser->GetHost()->WasResized();
|
m_browser->GetHost()->WasResized();
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
void CWeb::renderFrame (glm::ivec4 viewport)
|
||||||
void BrowserView::mouseMove(int x, int y)
|
|
||||||
{
|
{
|
||||||
m_mouse_x = x;
|
// ensure the virtual mouse position is up to date
|
||||||
m_mouse_y = y;
|
this->updateMouse (viewport);
|
||||||
|
// use the scene's framebuffer by default
|
||||||
|
glBindFramebuffer (GL_FRAMEBUFFER, this->getWallpaperFramebuffer());
|
||||||
|
// ensure we render over the whole framebuffer
|
||||||
|
glViewport (0, 0, this->getWidth (), this->getHeight ());
|
||||||
|
|
||||||
|
//Cef processes all messages, including OnPaint, which renders frame
|
||||||
|
//If there is no OnPaint in message loop, we will not update(render) frame
|
||||||
|
// This means some frames will not have OnPaint call in cef messageLoop
|
||||||
|
// Because of that glClear will result in flickering on higher fps
|
||||||
|
// Do not use glClear until some method to control rendering with cef is supported
|
||||||
|
//We might actually try to use cef to execute javascript, and not using off-screen rendering at all
|
||||||
|
//But for now let it be like this
|
||||||
|
// glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
CefDoMessageLoopWork();
|
||||||
|
}
|
||||||
|
void CWeb::updateMouse (glm::ivec4 viewport)
|
||||||
|
{
|
||||||
|
// update virtual mouse position first
|
||||||
|
glm::dvec2 position = this->getContext ().getInputContext ().getMouseInput ().position();
|
||||||
|
|
||||||
CefMouseEvent evt;
|
CefMouseEvent evt;
|
||||||
evt.x = x;
|
// Set mouse current position. Maybe clamps are not needed
|
||||||
evt.y = y;
|
evt.x = std::clamp(int(position.x - viewport.x),0,viewport.z);
|
||||||
|
evt.y = std::clamp(int(position.y - viewport.y),0,viewport.w);
|
||||||
bool mouse_leave = false; // TODO
|
// Send mouse position to cef
|
||||||
m_browser->GetHost()->SendMouseMoveEvent(evt, mouse_leave);
|
m_browser->GetHost()->SendMouseMoveEvent(evt, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
CWeb::~CWeb(){
|
||||||
void BrowserView::mouseClick(CefBrowserHost::MouseButtonType btn, bool mouse_up)
|
CefDoMessageLoopWork();
|
||||||
|
m_browser->GetHost()->CloseBrowser(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO Remove
|
||||||
|
GLuint compileShaderFromCode(GLenum shader_type, const char *src)
|
||||||
{
|
{
|
||||||
CefMouseEvent evt;
|
GLuint shader = glCreateShader(shader_type);
|
||||||
evt.x = m_mouse_x;
|
glShaderSource(shader, 1, &src, NULL);
|
||||||
evt.y = m_mouse_y;
|
glCompileShader(shader);
|
||||||
|
|
||||||
int click_count = 1; // TODO
|
GLint status;
|
||||||
m_browser->GetHost()->SendMouseClickEvent(evt, btn, mouse_up, click_count);
|
glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
|
||||||
|
if (status == GL_TRUE) {
|
||||||
|
return shader;
|
||||||
|
}
|
||||||
|
|
||||||
|
// shader compile fail!
|
||||||
|
fprintf(stderr, "SHADER COMPILE ERROR\n");
|
||||||
|
|
||||||
|
GLint info_len = 0;
|
||||||
|
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &info_len);
|
||||||
|
if (info_len > 1) {
|
||||||
|
char *info_log = (char*)malloc(sizeof(char) * info_len);
|
||||||
|
glGetShaderInfoLog(shader, info_len, NULL, info_log);
|
||||||
|
fprintf(stderr, "Error compiling shader: \n%s\n", info_log);
|
||||||
|
free(info_log);
|
||||||
|
}
|
||||||
|
glDeleteShader(shader);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
GLuint createShaderProgram(GLuint vert, GLuint frag)
|
||||||
void BrowserView::keyPress(int key, bool pressed)
|
|
||||||
{
|
{
|
||||||
CefKeyEvent evt;
|
GLuint program = glCreateProgram();
|
||||||
evt.character = key;
|
|
||||||
evt.native_key_code = key;
|
|
||||||
evt.type = pressed ? KEYEVENT_CHAR : KEYEVENT_KEYUP;
|
|
||||||
|
|
||||||
m_browser->GetHost()->SendKeyEvent(evt);
|
glAttachShader(program, vert);
|
||||||
|
glAttachShader(program, frag);
|
||||||
|
glLinkProgram(program);
|
||||||
|
glDetachShader(program, vert);
|
||||||
|
glDetachShader(program, frag);
|
||||||
|
|
||||||
|
GLint linked;
|
||||||
|
glGetProgramiv(program, GL_LINK_STATUS, &linked);
|
||||||
|
if (linked) {
|
||||||
|
return program;
|
||||||
|
}
|
||||||
|
|
||||||
|
// fail...
|
||||||
|
GLint info_len = 0;
|
||||||
|
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &info_len);
|
||||||
|
if (info_len > 1) {
|
||||||
|
char *info_log = (char*)malloc(sizeof(char) * info_len);
|
||||||
|
glGetProgramInfoLog(program, info_len, NULL, info_log);
|
||||||
|
fprintf(stderr, "Error linking program: \n%s\n", info_log);
|
||||||
|
free(info_log);
|
||||||
|
}
|
||||||
|
|
||||||
|
glDeleteProgram(program);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CWeb::RenderHandler::RenderHandler(CWeb* webdata):
|
||||||
|
m_webdata(webdata)
|
||||||
|
{
|
||||||
|
// m_prog = GLCore::createShaderProgram("shaders/tex.vert", "shaders/tex.frag");
|
||||||
|
|
||||||
|
//GLuint vertShader = compileShaderFromFile(GL_VERTEX_SHADER, vert);
|
||||||
|
|
||||||
|
|
||||||
|
// const char *vertCode = R"(
|
||||||
|
// #version 150
|
||||||
|
|
||||||
|
// uniform mat4 mvp;
|
||||||
|
// in vec2 position;
|
||||||
|
// out vec2 Texcoord;
|
||||||
|
|
||||||
|
// void main() {
|
||||||
|
// Texcoord = (vec2(position.x + 1.0f, position.y - 1.0f) * 0.5);
|
||||||
|
// Texcoord.y *= -1.0f;
|
||||||
|
// gl_Position = mvp * vec4(position.x, position.y, 0.0f, 1.0f);
|
||||||
|
// })";
|
||||||
|
// GLuint vertShader = compileShaderFromCode(GL_VERTEX_SHADER, vertCode);
|
||||||
|
|
||||||
|
// const char *fragCode = R"(
|
||||||
|
// #version 150
|
||||||
|
|
||||||
|
// in vec2 Texcoord;
|
||||||
|
|
||||||
|
// out vec4 outputColor;
|
||||||
|
|
||||||
|
// uniform sampler2D tex;
|
||||||
|
|
||||||
|
// void main() {
|
||||||
|
// outputColor = texture2D(tex, Texcoord);
|
||||||
|
// if (outputColor.a < 0.1)
|
||||||
|
// {
|
||||||
|
// discard;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// )";
|
||||||
|
// GLuint fragShader = compileShaderFromCode(GL_FRAGMENT_SHADER, fragCode);
|
||||||
|
|
||||||
|
// if (vertShader == 0 || fragShader == 0) {
|
||||||
|
// sLog.exception("Can't compile vert or frag shader in Web");
|
||||||
|
// }
|
||||||
|
|
||||||
|
// this->m_prog = createShaderProgram(vertShader, fragShader);
|
||||||
|
// if(this->m_prog==0){
|
||||||
|
// sLog.exception("Can't create program from shaders in Web");
|
||||||
|
// }
|
||||||
|
|
||||||
|
}
|
||||||
|
CWeb::RenderHandler::~RenderHandler(){
|
||||||
|
// glDeleteProgram(this->m_prog);
|
||||||
|
// glDeleteBuffers(1, &this->m_vbo);
|
||||||
|
// glDeleteVertexArrays(1, &this->m_vao);
|
||||||
|
}
|
||||||
|
//Required by CEF
|
||||||
|
void CWeb::RenderHandler::GetViewRect(CefRefPtr<CefBrowser> browser, CefRect &rect)
|
||||||
|
{
|
||||||
|
rect = CefRect(0, 0, this->m_webdata->getWidth(), this->m_webdata->getHeight());
|
||||||
|
}
|
||||||
|
//Will be executed in CEF message loop
|
||||||
|
void CWeb::RenderHandler::OnPaint(CefRefPtr<CefBrowser> browser, PaintElementType type,
|
||||||
|
const RectList &dirtyRects, const void *buffer,
|
||||||
|
int width, int height)
|
||||||
|
{
|
||||||
|
//sLog.debug("BrowserView::RenderHandler::OnPaint");
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, this->texture());
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_BGRA_EXT,
|
||||||
|
GL_UNSIGNED_BYTE, (unsigned char*)buffer);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
|
// GLCHECK(glActiveTexture(GL_TEXTURE0));
|
||||||
|
// GLCHECK(glBindTexture(GL_TEXTURE_2D, this->texture()));
|
||||||
|
// GLCHECK(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_BGRA_EXT,
|
||||||
|
// GL_UNSIGNED_BYTE, (unsigned char*)buffer));
|
||||||
|
// GLCHECK(glBindTexture(GL_TEXTURE_2D, 0));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string CWeb::Type = "web";
|
@ -1,187 +1,119 @@
|
|||||||
// This code is a modification of the original "cefsimple" example that can be found at
|
#pragma once
|
||||||
// https://bitbucket.org/chromiumembedded/cef/wiki/GeneralUsage
|
|
||||||
|
|
||||||
#ifndef BROWSERVIEW_HPP
|
|
||||||
# define BROWSERVIEW_HPP
|
|
||||||
|
|
||||||
# include <iostream>
|
|
||||||
|
|
||||||
// OpenGL
|
|
||||||
# include <GL/glew.h>
|
|
||||||
# include <GLFW/glfw3.h>
|
|
||||||
|
|
||||||
// Matrices manipulation for OpenGL
|
// Matrices manipulation for OpenGL
|
||||||
# include <glm/glm.hpp>
|
#include <glm/glm.hpp>
|
||||||
# include <glm/ext.hpp>
|
#include <glm/ext.hpp>
|
||||||
|
|
||||||
// Chromium Embedded Framework
|
#include <string>
|
||||||
# include <cef_render_handler.h>
|
#include <vector>
|
||||||
# include <cef_client.h>
|
#include <memory>
|
||||||
# include <cef_app.h>
|
#include <algorithm>
|
||||||
|
|
||||||
# include <string>
|
#include "common.h"
|
||||||
# include <vector>
|
#include "WallpaperEngine/Core/CWeb.h"
|
||||||
# include <memory>
|
#include "WallpaperEngine/Render/CWallpaper.h"
|
||||||
# include <algorithm>
|
#include "WallpaperEngine/Audio/CAudioStream.h"
|
||||||
|
|
||||||
// ****************************************************************************
|
namespace WallpaperEngine::Render
|
||||||
//! \brief Interface class rendering a single web page.
|
|
||||||
// ****************************************************************************
|
|
||||||
class BrowserView
|
|
||||||
{
|
{
|
||||||
public:
|
class CWeb : public CWallpaper
|
||||||
|
|
||||||
//! \brief Default Constructor using a given URL.
|
|
||||||
BrowserView(const std::string &url);
|
|
||||||
|
|
||||||
//! \brief
|
|
||||||
~BrowserView();
|
|
||||||
|
|
||||||
//! \brief Load the given web page.
|
|
||||||
void load(const std::string &url);
|
|
||||||
|
|
||||||
//! \brief Render the web page.
|
|
||||||
void draw();
|
|
||||||
|
|
||||||
//! \brief Set the windows size.
|
|
||||||
void reshape(int w, int h);
|
|
||||||
|
|
||||||
//! \brief Set the viewport: the rectangle on the window where to display
|
|
||||||
//! the web document.
|
|
||||||
//! \return false if arguments are incorrect.
|
|
||||||
bool viewport(float x, float y, float w, float h);
|
|
||||||
|
|
||||||
//! \brief Get the viewport.
|
|
||||||
inline glm::vec4 const& viewport() const
|
|
||||||
{
|
{
|
||||||
return m_viewport;
|
public:
|
||||||
}
|
CWeb (Core::CWeb* scene, CRenderContext& context, CAudioContext& audioContext);
|
||||||
|
~CWeb();
|
||||||
|
uint32_t getWidth () const override { return this->m_width; }
|
||||||
|
|
||||||
//! \brief TODO
|
uint32_t getHeight () const override { return this->m_height; }
|
||||||
// void executeJS(const std::string &cmd);
|
|
||||||
|
|
||||||
//! \brief Set the new mouse position
|
void setSize (int64_t width, int64_t height);
|
||||||
void mouseMove(int x, int y);
|
|
||||||
|
|
||||||
//! \brief Set the new mouse state (clicked ...)
|
protected:
|
||||||
void mouseClick(CefBrowserHost::MouseButtonType btn, bool mouse_up);
|
void renderFrame (glm::ivec4 viewport) override;
|
||||||
|
void updateMouse (glm::ivec4 viewport);
|
||||||
|
Core::CWeb* getWeb ()
|
||||||
|
{
|
||||||
|
return this->getWallpaperData ()->as<Core::CWeb> ();
|
||||||
|
}
|
||||||
|
|
||||||
//! \brief Set the new keyboard state (char typed ...)
|
friend class CWallpaper;
|
||||||
void keyPress(int key, bool pressed);
|
|
||||||
|
|
||||||
private:
|
static const std::string Type;
|
||||||
|
|
||||||
// *************************************************************************
|
private:
|
||||||
//! \brief Private implementation to handle CEF events to draw the web page.
|
// *************************************************************************
|
||||||
// *************************************************************************
|
//! \brief Private implementation to handle CEF events to draw the web page.
|
||||||
class RenderHandler: public CefRenderHandler
|
// *************************************************************************
|
||||||
{
|
class RenderHandler: public CefRenderHandler
|
||||||
public:
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
RenderHandler(glm::vec4 const& viewport);
|
RenderHandler(CWeb* webdata);
|
||||||
|
|
||||||
//! \brief
|
//! \brief
|
||||||
~RenderHandler();
|
~RenderHandler();
|
||||||
|
|
||||||
//! \brief Compile OpenGL shaders and create OpenGL objects (VAO,
|
//! \brief Compile OpenGL shaders and create OpenGL objects (VAO,
|
||||||
//! VBO, texture, locations ...)
|
//! VBO, texture, locations ...)
|
||||||
bool init();
|
bool init();
|
||||||
|
|
||||||
//! \brief Render OpenGL VAO (rotating a textured square)
|
//! \brief CefRenderHandler interface
|
||||||
void draw(glm::vec4 const& viewport, bool fixed);
|
virtual void GetViewRect(CefRefPtr<CefBrowser> browser, CefRect &rect) override;
|
||||||
|
|
||||||
//! \brief Resize the view
|
//! \brief CefRenderHandler interface
|
||||||
void reshape(int w, int h);
|
//! Update the OpenGL texture.
|
||||||
|
virtual void OnPaint(CefRefPtr<CefBrowser> browser, PaintElementType type,
|
||||||
|
const RectList &dirtyRects, const void *buffer,
|
||||||
|
int width, int height) override;
|
||||||
|
|
||||||
//! \brief Return the OpenGL texture handle
|
//! \brief CefBase interface
|
||||||
GLuint texture() const
|
IMPLEMENT_REFCOUNTING(RenderHandler);
|
||||||
{
|
|
||||||
return m_tex;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! \brief CefRenderHandler interface
|
private:
|
||||||
virtual void GetViewRect(CefRefPtr<CefBrowser> browser, CefRect &rect) override;
|
CWeb* m_webdata;
|
||||||
|
|
||||||
//! \brief CefRenderHandler interface
|
uint32_t getWidth () const {
|
||||||
//! Update the OpenGL texture.
|
return this->m_webdata->getWidth();
|
||||||
virtual void OnPaint(CefRefPtr<CefBrowser> browser, PaintElementType type,
|
};
|
||||||
const RectList &dirtyRects, const void *buffer,
|
uint32_t getHeight () const {
|
||||||
int width, int height) override;
|
return this->m_webdata->getHeight();
|
||||||
|
};
|
||||||
|
//! \brief Return the OpenGL texture handle
|
||||||
|
GLuint texture() const
|
||||||
|
{
|
||||||
|
return this->m_webdata->getWallpaperFramebuffer();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
//! \brief CefBase interface
|
// *************************************************************************
|
||||||
IMPLEMENT_REFCOUNTING(RenderHandler);
|
//! \brief Provide access to browser-instance-specific callbacks. A single
|
||||||
|
//! CefClient instance can be shared among any number of browsers.
|
||||||
|
// *************************************************************************
|
||||||
|
class BrowserClient: public CefClient
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
private:
|
BrowserClient(CefRefPtr<CefRenderHandler> ptr)
|
||||||
|
: m_renderHandler(ptr)
|
||||||
|
{}
|
||||||
|
|
||||||
//! \brief Dimension
|
virtual CefRefPtr<CefRenderHandler> GetRenderHandler() override
|
||||||
int m_width;
|
{
|
||||||
int m_height;
|
return m_renderHandler;
|
||||||
|
}
|
||||||
|
|
||||||
//! \brief Where to draw on the OpenGL window
|
CefRefPtr<CefRenderHandler> m_renderHandler;
|
||||||
glm::vec4 const& m_viewport;
|
|
||||||
|
|
||||||
//! \brief OpenGL shader program handle
|
IMPLEMENT_REFCOUNTING(BrowserClient);
|
||||||
GLuint m_prog = 0;
|
};
|
||||||
//! \brief OpenGL texture handle
|
|
||||||
GLuint m_tex = 0;
|
CefRefPtr<CefBrowser> m_browser;
|
||||||
//! \brief OpenGL vertex array object handle
|
CefRefPtr<BrowserClient> m_client;
|
||||||
GLuint m_vao = 0;
|
RenderHandler* m_render_handler = nullptr;
|
||||||
//! \brief OpenGL vertex buffer obejct handle
|
|
||||||
GLuint m_vbo = 0;
|
|
||||||
|
|
||||||
//! \brief OpenGL shader variable locations for vertices of the
|
int64_t m_width;
|
||||||
//! rectangle
|
int64_t m_height;
|
||||||
GLint m_pos_loc = -1;
|
|
||||||
//! \brief OpenGL shader variable locations for the texture
|
glm::vec2 m_mousePosition;
|
||||||
GLint m_tex_loc = -1;
|
glm::vec2 m_mousePositionLast;
|
||||||
//! \brief OpenGL shader variable locations for the Model View
|
|
||||||
//! Projection matrix.
|
|
||||||
GLint m_mvp_loc = -1;
|
|
||||||
};
|
};
|
||||||
|
}
|
||||||
// *************************************************************************
|
|
||||||
//! \brief Provide access to browser-instance-specific callbacks. A single
|
|
||||||
//! CefClient instance can be shared among any number of browsers.
|
|
||||||
// *************************************************************************
|
|
||||||
class BrowserClient: public CefClient
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
BrowserClient(CefRefPtr<CefRenderHandler> ptr)
|
|
||||||
: m_renderHandler(ptr)
|
|
||||||
{}
|
|
||||||
|
|
||||||
virtual CefRefPtr<CefRenderHandler> GetRenderHandler() override
|
|
||||||
{
|
|
||||||
return m_renderHandler;
|
|
||||||
}
|
|
||||||
|
|
||||||
CefRefPtr<CefRenderHandler> m_renderHandler;
|
|
||||||
|
|
||||||
IMPLEMENT_REFCOUNTING(BrowserClient);
|
|
||||||
};
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
//! \brief Mouse cursor position on the OpenGL window
|
|
||||||
int m_mouse_x;
|
|
||||||
int m_mouse_y;
|
|
||||||
|
|
||||||
//! \brief Where to draw on the OpenGL window
|
|
||||||
glm::vec4 m_viewport;
|
|
||||||
|
|
||||||
//! \brief Chromium Embedded framework elements
|
|
||||||
CefRefPtr<CefBrowser> m_browser;
|
|
||||||
CefRefPtr<BrowserClient> m_client;
|
|
||||||
RenderHandler* m_render_handler = nullptr;
|
|
||||||
|
|
||||||
//! \brief OpenGL has created GPU elements with success
|
|
||||||
bool m_initialized = false;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
//! \brief If set to false then the web page is turning.
|
|
||||||
bool m_fixed = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // BROWSERVIEW_HPP
|
|
||||||
|
@ -1,3 +1,8 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "WallpaperEngine/Logging/CLog.h"
|
#include "WallpaperEngine/Logging/CLog.h"
|
||||||
|
#include "WallpaperEngine/Core/CWeb.h"
|
||||||
|
|
||||||
|
//global variables are bad
|
||||||
|
extern bool g_CEFused;
|
||||||
|
extern CefMainArgs g_args;
|
Loading…
Reference in New Issue
Block a user