forked from cztomczak/cefcapi
-
Notifications
You must be signed in to change notification settings - Fork 0
/
main_linux.c
141 lines (117 loc) · 4.51 KB
/
main_linux.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
// CEF C API example
// Project website: https://github.com/cztomczak/cefcapi
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <X11/Xlib.h>
#include <gdk/gdkx.h>
#include "gtk.h"
#include "capi/cef_base.h"
#include "capi/cef_app.h"
#include "capi/cef_client.h"
#include "capi/cef_life_span_handler.h"
// Globals
cef_life_span_handler_t g_life_span_handler = {}; // not used currently
// Signatures
int x11_error_handler(Display *display, XErrorEvent *event);
int x11_io_error_handler(Display *display);
int main(int argc, char** argv) {
// This executable is called many times, because it
// is also used for subprocesses. Let's print args
// so we can differentiate between main process and
// subprocesses. If one of the first args is for
// example "--type=renderer" then it means that
// this is a Renderer process. There may be more
// subprocesses like GPU (--type=gpu-process) and
// others. On Linux there are also special Zygote
// processes.
printf("\nProcess args: ");
if (argc == 1) {
printf("none (Main process)");
} else {
for (int i = 1; i < argc; i++) {
if (strlen(argv[i]) > 128)
printf("... ");
else
printf("%s ", argv[i]);
}
}
printf("\n\n");
// Main args.
cef_main_args_t main_args = {};
main_args.argc = argc;
main_args.argv = argv;
cef_app_t app = {};
initialize_cef_app(&app);
// Execute subprocesses. It is also possible to have
// a separate executable for subprocesses by setting
// cef_settings_t.browser_subprocess_path. In such
// case cef_execute_process should not be called here.
printf("cef_execute_process, argc=%d\n", argc);
int code = cef_execute_process(&main_args, &app, NULL);
if (code >= 0) {
_exit(code);
}
// Application settings. It is mandatory to set the
// "size" member.
cef_settings_t settings = {};
settings.size = sizeof(cef_settings_t);
settings.log_severity = LOGSEVERITY_WARNING; // Show only warnings/errors
settings.no_sandbox = 1;
// Initialize CEF.
printf("cef_initialize\n");
cef_initialize(&main_args, &settings, &app, NULL);
// Create GTK window. Alternatively you can pass a NULL handle
// to CEF and then it will create a window of its own.
// When passing NULL you have to implement cef_life_span_handler_t
// and call cef_quit_message_loop from the on_before_close
// callback. Example initialization of this handler and its
// callback is Windows example.
initialize_gtk();
GtkWidget* gtk_window = create_gtk_window("cefcapi example", 800, 600);
cef_window_info_t window_info = {};
#if GTK_CHECK_VERSION(3,0,0)
Window xid = gdk_x11_window_get_xid(gtk_widget_get_window(gtk_window));
#else
Window xid = gdk_x11_drawable_get_xid(gtk_widget_get_window(gtk_window));
#endif
printf("Window xid %u\n", (unsigned) xid);
window_info.parent_window = xid;
// Copied from upstream cefclient. Install xlib error
// handlers so that the application won't be terminated on
// non-fatal errors. Must be done after initializing GTK.
XSetErrorHandler(x11_error_handler);
XSetIOErrorHandler(x11_io_error_handler);
// Initial url
char url[] = "https://www.google.com/ncr";
cef_string_t cef_url = {};
cef_string_utf8_to_utf16(url, strlen(url), &cef_url);
// Browser settings. It is mandatory to set the
// "size" member.
cef_browser_settings_t browser_settings = {};
browser_settings.size = sizeof(cef_browser_settings_t);
// Client handler and its callbacks
cef_client_t client = {};
initialize_cef_client(&client);
// Create browser asynchronously. There is also a
// synchronous version of this function available.
printf("cef_browser_host_create_browser\n");
cef_browser_host_create_browser(&window_info, &client, &cef_url,
&browser_settings, NULL);
// Message loop. There is also cef_do_message_loop_work()
// that allow for integrating with existing message loops.
printf("cef_run_message_loop\n");
cef_run_message_loop();
// Shutdown CEF
printf("cef_shutdown\n");
cef_shutdown();
return 0;
}
int x11_error_handler(Display *display, XErrorEvent *event) {
printf("X11 error: type=%d, serial=%lu, code=%d\n",
event->type, event->serial, (int)event->error_code);
return 0;
}
int x11_io_error_handler(Display *display) {
return 0;
}