1 /******************************************************************************
2  Copyright (C) 2014 by John R. Bradley <jrb@turrettech.com>
3  Copyright (C) 2018 by Hugh Bailey ("Jim") <jim@obsproject.com>
4 
5  This program is free software: you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation, either version 2 of the License, or
8  (at your option) any later version.
9 
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with this program.  If not, see <http://www.gnu.org/licenses/>.
17  ******************************************************************************/
18 
19 #pragma once
20 
21 #include <map>
22 #include <unordered_map>
23 #include <functional>
24 #include "cef-headers.hpp"
25 
26 typedef std::function<void(CefRefPtr<CefBrowser>)> BrowserFunc;
27 
28 #ifdef USE_QT_LOOP
29 #include <QObject>
30 #include <QTimer>
31 #include <mutex>
32 #include <deque>
33 
34 typedef std::function<void()> MessageTask;
35 
36 class MessageObject : public QObject {
37 	Q_OBJECT
38 
39 	friend void QueueBrowserTask(CefRefPtr<CefBrowser> browser,
40 				     BrowserFunc func);
41 
42 	struct Task {
43 		CefRefPtr<CefBrowser> browser;
44 		BrowserFunc func;
45 
TaskMessageObject::Task46 		inline Task() {}
TaskMessageObject::Task47 		inline Task(CefRefPtr<CefBrowser> browser_, BrowserFunc func_)
48 			: browser(browser_), func(func_)
49 		{
50 		}
51 	};
52 
53 	std::mutex browserTaskMutex;
54 	std::deque<Task> browserTasks;
55 
56 public slots:
57 	bool ExecuteNextBrowserTask();
58 	void ExecuteTask(MessageTask task);
59 	void DoCefMessageLoop(int ms);
60 	void Process();
61 };
62 
63 extern void QueueBrowserTask(CefRefPtr<CefBrowser> browser, BrowserFunc func);
64 #endif
65 
66 class BrowserApp : public CefApp,
67 		   public CefRenderProcessHandler,
68 		   public CefBrowserProcessHandler,
69 		   public CefV8Handler {
70 
71 	void ExecuteJSFunction(CefRefPtr<CefBrowser> browser,
72 			       const char *functionName,
73 			       CefV8ValueList arguments);
74 
75 	typedef std::map<int, CefRefPtr<CefV8Value>> CallbackMap;
76 
77 	bool shared_texture_available;
78 	CallbackMap callbackMap;
79 	int callbackId;
80 
81 public:
BrowserApp(bool shared_texture_available_=false)82 	inline BrowserApp(bool shared_texture_available_ = false)
83 		: shared_texture_available(shared_texture_available_)
84 	{
85 	}
86 
87 	virtual CefRefPtr<CefRenderProcessHandler>
88 	GetRenderProcessHandler() override;
89 	virtual CefRefPtr<CefBrowserProcessHandler>
90 	GetBrowserProcessHandler() override;
91 	virtual void OnBeforeChildProcessLaunch(
92 		CefRefPtr<CefCommandLine> command_line) override;
93 	virtual void OnRegisterCustomSchemes(
94 		CefRawPtr<CefSchemeRegistrar> registrar) override;
95 	virtual void OnBeforeCommandLineProcessing(
96 		const CefString &process_type,
97 		CefRefPtr<CefCommandLine> command_line) override;
98 	virtual void OnContextCreated(CefRefPtr<CefBrowser> browser,
99 				      CefRefPtr<CefFrame> frame,
100 				      CefRefPtr<CefV8Context> context) override;
101 	virtual bool
102 	OnProcessMessageReceived(CefRefPtr<CefBrowser> browser,
103 #if CHROME_VERSION_BUILD >= 3770
104 				 CefRefPtr<CefFrame> frame,
105 #endif
106 				 CefProcessId source_process,
107 				 CefRefPtr<CefProcessMessage> message) override;
108 	virtual bool Execute(const CefString &name,
109 			     CefRefPtr<CefV8Value> object,
110 			     const CefV8ValueList &arguments,
111 			     CefRefPtr<CefV8Value> &retval,
112 			     CefString &exception) override;
113 
114 #ifdef USE_QT_LOOP
115 	virtual void OnScheduleMessagePumpWork(int64 delay_ms) override;
116 	QTimer frameTimer;
117 #endif
118 
119 #if !ENABLE_WASHIDDEN
120 	std::unordered_map<int, bool> browserVis;
121 
122 	void SetFrameDocumentVisibility(CefRefPtr<CefBrowser> browser,
123 					CefRefPtr<CefFrame> frame,
124 					bool isVisible);
125 	void SetDocumentVisibility(CefRefPtr<CefBrowser> browser,
126 				   bool isVisible);
127 #endif
128 
129 	IMPLEMENT_REFCOUNTING(BrowserApp);
130 };
131