82
struct weston_input_device base;
95
struct weston_seat base;
98
static struct xkb_keymap *
99
x11_compositor_get_keymap(struct x11_compositor *c)
101
xcb_get_property_cookie_t cookie;
102
xcb_get_property_reply_t *reply;
103
xcb_generic_error_t *error;
104
struct xkb_rule_names names;
105
struct xkb_keymap *ret;
106
const char *value_all, *value_part;
107
int length_all, length_part;
109
memset(&names, 0, sizeof(names));
111
cookie = xcb_get_property(c->conn, 0, c->screen->root,
112
c->atom.xkb_names, c->atom.string, 0, 1024);
113
reply = xcb_get_property_reply(c->conn, cookie, &error);
117
value_all = xcb_get_property_value(reply);
118
length_all = xcb_get_property_value_length(reply);
119
value_part = value_all;
121
#define copy_prop_value(to) \
122
length_part = strlen(value_part); \
123
if (value_part + length_part < (value_all + length_all) && \
125
names.to = value_part; \
126
value_part += length_part + 1;
128
copy_prop_value(rules);
129
copy_prop_value(model);
130
copy_prop_value(layout);
131
copy_prop_value(variant);
132
copy_prop_value(options);
133
#undef copy_prop_value
135
ret = xkb_map_new_from_names(c->base.xkb_context, &names, 0);
142
x11_compositor_setup_xkb(struct x11_compositor *c)
145
weston_log("XCB-XKB not available during build\n");
147
c->xkb_event_base = 0;
150
const xcb_query_extension_reply_t *ext;
151
xcb_generic_error_t *error;
152
xcb_void_cookie_t select;
153
xcb_xkb_per_client_flags_cookie_t pcf;
154
xcb_xkb_per_client_flags_reply_t *pcf_reply;
157
c->xkb_event_base = 0;
159
ext = xcb_get_extension_data(c->conn, &xcb_xkb_id);
161
weston_log("XKB extension not available on host X11 server\n");
164
c->xkb_event_base = ext->first_event;
166
select = xcb_xkb_select_events(c->conn,
167
XCB_XKB_ID_USE_CORE_KBD,
168
XCB_XKB_EVENT_TYPE_STATE_NOTIFY,
170
XCB_XKB_EVENT_TYPE_STATE_NOTIFY,
174
error = xcb_request_check(c->conn, select);
176
weston_log("error: failed to select for XKB state events\n");
180
pcf = xcb_xkb_per_client_flags(c->conn,
181
XCB_XKB_ID_USE_CORE_KBD,
182
XCB_XKB_PER_CLIENT_FLAG_DETECTABLE_AUTO_REPEAT,
183
XCB_XKB_PER_CLIENT_FLAG_DETECTABLE_AUTO_REPEAT,
187
pcf_reply = xcb_xkb_per_client_flags_reply(c->conn, pcf, &error);
190
weston_log("failed to set XKB per-client flags, not using "
191
"detectable repeat\n");
87
x11_input_create(struct x11_compositor *c)
200
x11_input_create(struct x11_compositor *c, int no_input)
89
202
struct x11_input *input;
203
struct xkb_keymap *keymap;
91
205
input = malloc(sizeof *input);
92
206
if (input == NULL)
95
209
memset(input, 0, sizeof *input);
96
weston_input_device_init(&input->base, &c->base);
98
c->base.input_device = &input->base.input_device;
210
weston_seat_init(&input->base, &c->base);
211
c->base.seat = &input->base;
216
weston_seat_init_pointer(&input->base);
218
x11_compositor_setup_xkb(c);
220
keymap = x11_compositor_get_keymap(c);
221
weston_seat_init_keyboard(&input->base, keymap);
223
xkb_map_unref(keymap);
134
c->base.display = eglGetDisplay(c->dpy);
135
if (c->base.display == NULL) {
136
fprintf(stderr, "failed to create display\n");
140
if (!eglInitialize(c->base.display, &major, &minor)) {
141
fprintf(stderr, "failed to initialize display\n");
145
extensions = eglQueryString(c->base.display, EGL_EXTENSIONS);
146
if (!strstr(extensions, "EGL_KHR_surfaceless_gles2")) {
147
fprintf(stderr, "EGL_KHR_surfaceless_gles2 not available\n");
257
static const EGLint pbuffer_attribs[] = {
263
c->base.egl_display = eglGetDisplay(c->dpy);
264
if (c->base.egl_display == NULL) {
265
weston_log("failed to create display\n");
269
if (!eglInitialize(c->base.egl_display, &major, &minor)) {
270
weston_log("failed to initialize display\n");
151
274
if (!eglBindAPI(EGL_OPENGL_ES_API)) {
152
fprintf(stderr, "failed to bind EGL_OPENGL_ES_API\n");
155
if (!eglChooseConfig(c->base.display, config_attribs,
156
&c->base.config, 1, &n) || n == 0) {
157
fprintf(stderr, "failed to choose config: %d\n", n);
161
c->base.context = eglCreateContext(c->base.display, c->base.config,
162
EGL_NO_CONTEXT, context_attribs);
163
if (c->base.context == NULL) {
164
fprintf(stderr, "failed to create context\n");
168
if (!eglMakeCurrent(c->base.display, EGL_NO_SURFACE,
169
EGL_NO_SURFACE, c->base.context)) {
170
fprintf(stderr, "failed to make context current\n");
275
weston_log("failed to bind EGL_OPENGL_ES_API\n");
278
if (!eglChooseConfig(c->base.egl_display, config_attribs,
279
&c->base.egl_config, 1, &n) || n == 0) {
280
weston_log("failed to choose config: %d\n", n);
284
c->base.egl_context =
285
eglCreateContext(c->base.egl_display, c->base.egl_config,
286
EGL_NO_CONTEXT, context_attribs);
287
if (c->base.egl_context == NULL) {
288
weston_log("failed to create context\n");
292
c->dummy_pbuffer = eglCreatePbufferSurface(c->base.egl_display,
295
if (c->dummy_pbuffer == NULL) {
296
weston_log("failed to create dummy pbuffer\n");
300
if (!eglMakeCurrent(c->base.egl_display, c->dummy_pbuffer,
301
c->dummy_pbuffer, c->base.egl_context)) {
302
weston_log("failed to make context current\n");
178
310
x11_compositor_fini_egl(struct x11_compositor *compositor)
180
eglMakeCurrent(compositor->base.display,
312
eglMakeCurrent(compositor->base.egl_display,
181
313
EGL_NO_SURFACE, EGL_NO_SURFACE,
184
eglTerminate(compositor->base.display);
316
eglTerminate(compositor->base.egl_display);
185
317
eglReleaseThread();
189
x11_output_prepare_render(struct weston_output *output_base)
321
x11_output_repaint(struct weston_output *output_base,
322
pixman_region32_t *damage)
191
struct x11_output *output = (struct x11_output *) output_base;
192
struct weston_compositor *ec = output->base.compositor;
324
struct x11_output *output = (struct x11_output *)output_base;
325
struct x11_compositor *compositor =
326
(struct x11_compositor *)output->base.compositor;
327
struct weston_surface *surface;
194
if (!eglMakeCurrent(ec->display, output->egl_surface,
195
output->egl_surface, ec->context)) {
196
fprintf(stderr, "failed to make current\n");
329
if (!eglMakeCurrent(compositor->base.egl_display, output->egl_surface,
331
compositor->base.egl_context)) {
332
weston_log("failed to make current\n");
336
wl_list_for_each_reverse(surface, &compositor->base.surface_list, link)
337
weston_surface_draw(surface, &output->base, damage);
339
wl_signal_emit(&output->base.frame_signal, output);
341
eglSwapBuffers(compositor->base.egl_display, output->egl_surface);
343
wl_event_source_timer_update(output->finish_frame_timer, 10);
218
x11_output_present(struct weston_output *output_base)
220
struct x11_output *output = (struct x11_output *) output_base;
221
struct weston_compositor *ec = output->base.compositor;
223
if (x11_output_prepare_render(&output->base))
226
eglSwapBuffers(ec->display, output->egl_surface);
228
wl_event_source_timer_update(output->finish_frame_timer, 10);
234
x11_output_prepare_scanout_surface(struct weston_output *output_base,
235
struct weston_surface *es)
241
x11_output_set_cursor(struct weston_output *output_base,
242
struct weston_input_device *input)
248
361
x11_output_destroy(struct weston_output *output_base)
332
445
x11_output_set_icon(struct x11_compositor *c,
333
446
struct x11_output *output, const char *filename)
335
uint32_t *icon, *pixels, stride;
336
449
int32_t width, height;
450
pixman_image_t *image;
338
pixels = weston_load_image(filename, &width, &height, &stride);
452
image = load_image(filename);
455
width = pixman_image_get_width(image);
456
height = pixman_image_get_height(image);
341
457
icon = malloc(width * height * 4 + 8);
459
pixman_image_unref(image);
348
464
icon[1] = height;
349
memcpy(icon + 2, pixels, width * height * 4);
465
memcpy(icon + 2, pixman_image_get_data(image), width * height * 4);
350
466
xcb_change_property(c->conn, XCB_PROP_MODE_REPLACE, output->window,
351
467
c->atom.net_wm_icon, c->atom.cardinal, 32,
352
468
width * height + 2, icon);
470
pixman_image_unref(image);
358
474
x11_compositor_create_output(struct x11_compositor *c, int x, int y,
359
int width, int height, int fullscreen)
475
int width, int height, int fullscreen,
361
478
static const char name[] = "Weston Compositor";
362
479
static const char class[] = "weston-1\0Weston Compositor";
365
482
struct wm_normal_hints normal_hints;
366
483
struct wl_event_loop *loop;
367
484
uint32_t mask = XCB_CW_EVENT_MASK | XCB_CW_CURSOR;
368
uint32_t values[2] = {
369
XCB_EVENT_MASK_KEY_PRESS |
370
XCB_EVENT_MASK_KEY_RELEASE |
371
XCB_EVENT_MASK_BUTTON_PRESS |
372
XCB_EVENT_MASK_BUTTON_RELEASE |
373
XCB_EVENT_MASK_POINTER_MOTION |
485
uint32_t values[2] = {
374
486
XCB_EVENT_MASK_EXPOSURE |
375
XCB_EVENT_MASK_STRUCTURE_NOTIFY |
376
XCB_EVENT_MASK_ENTER_WINDOW |
377
XCB_EVENT_MASK_LEAVE_WINDOW |
378
XCB_EVENT_MASK_KEYMAP_STATE |
379
XCB_EVENT_MASK_FOCUS_CHANGE,
487
XCB_EVENT_MASK_STRUCTURE_NOTIFY,
493
XCB_EVENT_MASK_KEY_PRESS |
494
XCB_EVENT_MASK_KEY_RELEASE |
495
XCB_EVENT_MASK_BUTTON_PRESS |
496
XCB_EVENT_MASK_BUTTON_RELEASE |
497
XCB_EVENT_MASK_POINTER_MOTION |
498
XCB_EVENT_MASK_ENTER_WINDOW |
499
XCB_EVENT_MASK_LEAVE_WINDOW |
500
XCB_EVENT_MASK_KEYMAP_STATE |
501
XCB_EVENT_MASK_FOCUS_CHANGE;
383
503
output = malloc(sizeof *output);
384
504
if (output == NULL)
390
510
WL_OUTPUT_MODE_CURRENT | WL_OUTPUT_MODE_PREFERRED;
391
511
output->mode.width = width;
392
512
output->mode.height = height;
393
output->mode.refresh = 60;
513
output->mode.refresh = 60000;
394
514
wl_list_init(&output->base.mode_list);
395
515
wl_list_insert(&output->base.mode_list, &output->mode.link);
397
517
output->base.current = &output->mode;
518
output->base.make = "xwayland";
519
output->base.model = "none";
398
520
weston_output_init(&output->base, &c->base, x, y, width, height,
399
521
WL_OUTPUT_FLIPPED);
445
567
c->atom.net_wm_state_fullscreen);
447
569
output->egl_surface =
448
eglCreateWindowSurface(c->base.display, c->base.config,
570
eglCreateWindowSurface(c->base.egl_display, c->base.egl_config,
449
571
output->window, NULL);
450
572
if (!output->egl_surface) {
451
fprintf(stderr, "failed to create window surface\n");
573
weston_log("failed to create window surface\n");
454
if (!eglMakeCurrent(c->base.display, output->egl_surface,
455
output->egl_surface, c->base.context)) {
456
fprintf(stderr, "failed to make surface current\n");
576
if (!eglMakeCurrent(c->base.egl_display, output->egl_surface,
577
output->egl_surface, c->base.egl_context)) {
578
weston_log("failed to make surface current\n");
461
583
output->finish_frame_timer =
462
584
wl_event_loop_add_timer(loop, finish_frame_handler, output);
464
output->base.prepare_render = x11_output_prepare_render;
465
output->base.present = x11_output_present;
466
output->base.prepare_scanout_surface =
467
x11_output_prepare_scanout_surface;
468
output->base.set_hardware_cursor = x11_output_set_cursor;
586
output->base.origin = output->base.current;
587
output->base.repaint = x11_output_repaint;
469
588
output->base.destroy = x11_output_destroy;
589
output->base.assign_planes = NULL;
590
output->base.set_backlight = NULL;
591
output->base.set_dpms = NULL;
592
output->base.switch_mode = NULL;
471
594
wl_list_insert(c->base.output_list.prev, &output->base.link);
596
weston_log("x11 output %dx%d, window id %d\n",
597
width, height, output->window);
616
get_xkb_mod_mask(struct x11_compositor *c, uint32_t in)
618
struct weston_xkb_info *info = &c->base.seat->xkb_info;
621
if ((in & ShiftMask) && info->shift_mod != XKB_MOD_INVALID)
622
ret |= (1 << info->shift_mod);
623
if ((in & LockMask) && info->caps_mod != XKB_MOD_INVALID)
624
ret |= (1 << info->caps_mod);
625
if ((in & ControlMask) && info->ctrl_mod != XKB_MOD_INVALID)
626
ret |= (1 << info->ctrl_mod);
627
if ((in & Mod1Mask) && info->alt_mod != XKB_MOD_INVALID)
628
ret |= (1 << info->alt_mod);
629
if ((in & Mod2Mask) && info->mod2_mod != XKB_MOD_INVALID)
630
ret |= (1 << info->mod2_mod);
631
if ((in & Mod3Mask) && info->mod3_mod != XKB_MOD_INVALID)
632
ret |= (1 << info->mod3_mod);
633
if ((in & Mod4Mask) && info->super_mod != XKB_MOD_INVALID)
634
ret |= (1 << info->super_mod);
635
if ((in & Mod5Mask) && info->mod5_mod != XKB_MOD_INVALID)
636
ret |= (1 << info->mod5_mod);
643
update_xkb_state(struct x11_compositor *c, xcb_xkb_state_notify_event_t *state)
645
struct weston_compositor *ec = &c->base;
646
struct wl_seat *seat = &ec->seat->seat;
648
xkb_state_update_mask(c->base.seat->xkb_state.state,
649
get_xkb_mod_mask(c, state->baseMods),
650
get_xkb_mod_mask(c, state->latchedMods),
651
get_xkb_mod_mask(c, state->lockedMods),
656
notify_modifiers(seat, wl_display_next_serial(c->base.wl_display));
661
* This is monumentally unpleasant. If we don't have XCB-XKB bindings,
662
* the best we can do (given that XCB also lacks XI2 support), is to take
663
* the state from the core key events. Unfortunately that only gives us
664
* the effective (i.e. union of depressed/latched/locked) state, and we
665
* need the granularity.
667
* So we still update the state with every key event we see, but also use
668
* the state field from X11 events as a mask so we don't get any stuck
672
update_xkb_state_from_core(struct x11_compositor *c, uint16_t x11_mask)
674
uint32_t mask = get_xkb_mod_mask(c, x11_mask);
675
struct wl_keyboard *keyboard = &c->base.seat->keyboard;
677
xkb_state_update_mask(c->base.seat->xkb_state.state,
678
keyboard->modifiers.mods_depressed & mask,
679
keyboard->modifiers.mods_latched & mask,
680
keyboard->modifiers.mods_locked & mask,
683
(x11_mask >> 13) & 3);
684
notify_modifiers(&c->base.seat->seat,
685
wl_display_next_serial(c->base.wl_display));
490
689
x11_compositor_deliver_button_event(struct x11_compositor *c,
491
690
xcb_generic_event_t *event, int state)
493
692
xcb_button_press_event_t *button_event =
494
693
(xcb_button_press_event_t *) event;
697
update_xkb_state_from_core(c, button_event->state);
497
699
switch (button_event->detail) {
505
707
button = BTN_RIGHT;
711
notify_axis(&c->base.seat->seat,
712
weston_compositor_get_time(),
713
WL_POINTER_AXIS_VERTICAL_SCROLL,
714
wl_fixed_from_int(1));
718
notify_axis(&c->base.seat->seat,
719
weston_compositor_get_time(),
720
WL_POINTER_AXIS_VERTICAL_SCROLL,
721
wl_fixed_from_int(-1));
725
notify_axis(&c->base.seat->seat,
726
weston_compositor_get_time(),
727
WL_POINTER_AXIS_HORIZONTAL_SCROLL,
728
wl_fixed_from_int(1));
511
/* X11 sends wheel events as buttons events. But
512
* linux input treats as REL_WHEEL, therefore not
513
* button type at all. When we update the input
514
* protocol and get the 'axis' event, we'll send
515
* scroll events as axis events. */
732
notify_axis(&c->base.seat->seat,
733
weston_compositor_get_time(),
734
WL_POINTER_AXIS_HORIZONTAL_SCROLL,
735
wl_fixed_from_int(-1));
519
notify_button(c->base.input_device,
520
weston_compositor_get_time(), button, state);
739
notify_button(&c->base.seat->seat,
740
weston_compositor_get_time(), button,
741
state ? WL_POINTER_BUTTON_STATE_PRESSED :
742
WL_POINTER_BUTTON_STATE_RELEASED);
549
771
xcb_key_press_event_t *key_press, *key_release;
550
772
xcb_keymap_notify_event_t *keymap_notify;
551
773
xcb_focus_in_event_t *focus_in;
774
xcb_expose_event_t *expose;
557
783
while (x11_compositor_next_event(c, &event, mask)) {
558
784
switch (prev ? prev->response_type & ~0x80 : 0x80) {
559
785
case XCB_KEY_RELEASE:
786
/* Suppress key repeat events; this is only used if we
787
* don't have XCB XKB support. */
560
788
key_release = (xcb_key_press_event_t *) prev;
561
789
key_press = (xcb_key_press_event_t *) event;
562
790
if ((event->response_type & ~0x80) == XCB_KEY_PRESS &&
597
828
output = x11_compositor_find_output(c, focus_in->event);
598
notify_keyboard_focus(c->base.input_device,
599
weston_compositor_get_time(),
600
&output->base, &c->keys);
829
/* Unfortunately the state only comes with the enter
830
* event, rather than with the focus event. I'm not
831
* sure of the exact semantics around it and whether
832
* we can ensure that we get both? */
833
notify_keyboard_focus_in(&c->base.seat->seat, &c->keys,
834
STATE_UPDATE_AUTOMATIC);
611
845
switch (event->response_type & ~0x80) {
612
846
case XCB_KEY_PRESS:
613
847
key_press = (xcb_key_press_event_t *) event;
614
notify_key(c->base.input_device,
849
update_xkb_state_from_core(c, key_press->state);
850
notify_key(&c->base.seat->seat,
615
851
weston_compositor_get_time(),
616
key_press->detail - 8, 1);
852
key_press->detail - 8,
853
WL_KEYBOARD_KEY_STATE_PRESSED,
854
c->has_xkb ? STATE_UPDATE_NONE :
855
STATE_UPDATE_AUTOMATIC);
618
857
case XCB_KEY_RELEASE:
858
/* If we don't have XKB, we need to use the lame
859
* autorepeat detection above. */
864
key_release = (xcb_key_press_event_t *) event;
865
notify_key(&c->base.seat->seat,
866
weston_compositor_get_time(),
867
key_release->detail - 8,
868
WL_KEYBOARD_KEY_STATE_RELEASED,
621
871
case XCB_BUTTON_PRESS:
622
872
x11_compositor_deliver_button_event(c, event, 1);
627
877
case XCB_MOTION_NOTIFY:
628
878
motion_notify = (xcb_motion_notify_event_t *) event;
880
update_xkb_state_from_core(c, motion_notify->state);
629
881
output = x11_compositor_find_output(c, motion_notify->event);
630
notify_motion(c->base.input_device,
631
weston_compositor_get_time(),
632
output->base.x + motion_notify->event_x,
633
output->base.y + motion_notify->event_y);
882
x = wl_fixed_from_int(output->base.x + motion_notify->event_x);
883
y = wl_fixed_from_int(output->base.y + motion_notify->event_y);
884
notify_motion(&c->base.seat->seat,
885
weston_compositor_get_time(), x, y);
637
/* FIXME: schedule output repaint */
638
/* output = x11_compositor_find_output(c, expose->window); */
640
weston_compositor_schedule_repaint(&c->base);
889
expose = (xcb_expose_event_t *) event;
890
output = x11_compositor_find_output(c, expose->window);
891
weston_output_schedule_repaint(&output->base);
643
894
case XCB_ENTER_NOTIFY:
644
895
enter_notify = (xcb_enter_notify_event_t *) event;
645
896
if (enter_notify->state >= Button1Mask)
899
update_xkb_state_from_core(c, enter_notify->state);
647
900
output = x11_compositor_find_output(c, enter_notify->event);
648
notify_pointer_focus(c->base.input_device,
649
weston_compositor_get_time(),
651
output->base.x + enter_notify->event_x,
652
output->base.y + enter_notify->event_y);
901
x = wl_fixed_from_int(output->base.x + enter_notify->event_x);
902
y = wl_fixed_from_int(output->base.y + enter_notify->event_y);
904
notify_pointer_focus(&c->base.seat->seat,
905
&output->base, x, y);
655
908
case XCB_LEAVE_NOTIFY:
656
909
enter_notify = (xcb_enter_notify_event_t *) event;
657
910
if (enter_notify->state >= Button1Mask)
913
update_xkb_state_from_core(c, enter_notify->state);
659
914
output = x11_compositor_find_output(c, enter_notify->event);
660
notify_pointer_focus(c->base.input_device,
661
weston_compositor_get_time(),
663
output->base.x + enter_notify->event_x,
664
output->base.y + enter_notify->event_y);
915
notify_pointer_focus(&c->base.seat->seat, NULL, 0, 0);
667
918
case XCB_CLIENT_MESSAGE:
684
935
if (focus_in->mode == XCB_NOTIFY_MODE_WHILE_GRABBED ||
685
936
focus_in->mode == XCB_NOTIFY_MODE_UNGRAB)
687
notify_keyboard_focus(c->base.input_device,
688
weston_compositor_get_time(),
938
notify_keyboard_focus_out(&c->base.seat->seat);
947
(event->response_type & ~0x80) == c->xkb_event_base) {
948
xcb_xkb_state_notify_event_t *state =
949
(xcb_xkb_state_notify_event_t *) event;
950
if (state->xkbType == XCB_XKB_STATE_NOTIFY)
951
update_xkb_state(c, state);
696
956
if (prev != event)
731
994
{ "STRING", F(atom.string) },
732
995
{ "UTF8_STRING", F(atom.utf8_string) },
733
996
{ "CARDINAL", F(atom.cardinal) },
997
{ "_XKB_RULES_NAMES", F(atom.xkb_names) },
736
1000
xcb_intern_atom_cookie_t cookies[ARRAY_LENGTH(atoms)];
737
1001
xcb_intern_atom_reply_t *reply;
738
1002
xcb_pixmap_t pixmap;
741
1005
uint8_t data[] = { 0, 0, 0, 0 };
743
1007
for (i = 0; i < ARRAY_LENGTH(atoms); i++)
783
1047
static struct weston_compositor *
784
1048
x11_compositor_create(struct wl_display *display,
785
int width, int height, int count, int fullscreen)
1049
int width, int height, int count, int fullscreen,
1051
int argc, char *argv[], const char *config_file)
787
1053
struct x11_compositor *c;
788
struct wl_event_loop *loop;
789
1054
xcb_screen_iterator_t s;
1057
weston_log("initializing x11 backend\n");
792
1059
c = malloc(sizeof *c);
796
1063
memset(c, 0, sizeof *c);
1065
if (weston_compositor_init(&c->base, display, argc, argv,
798
1069
c->dpy = XOpenDisplay(NULL);
799
1070
if (c->dpy == NULL)
802
1073
c->conn = XGetXCBConnection(c->dpy);
803
1074
XSetEventQueueOwner(c->dpy, XCBOwnsEventQueue);
805
1076
if (xcb_connection_has_error(c->conn))
808
1079
s = xcb_setup_roots_iterator(xcb_get_setup(c->conn));
809
1080
c->screen = s.data;
814
1085
c->base.wl_display = display;
815
1086
if (x11_compositor_init_egl(c) < 0)
818
1089
c->base.destroy = x11_destroy;
820
/* Can't init base class until we have a current egl context */
821
if (weston_compositor_init(&c->base, display) < 0)
1091
if (weston_compositor_init_gl(&c->base) < 0)
1094
if (x11_input_create(c, no_input) < 0)
824
1097
for (i = 0, x = 0; i < count; i++) {
825
1098
if (x11_compositor_create_output(c, x, 0, width, height,
1099
fullscreen, no_input) < 0)
831
if (x11_input_create(c) < 0)
834
loop = wl_display_get_event_loop(c->base.wl_display);
837
wl_event_loop_add_fd(loop, xcb_get_file_descriptor(c->conn),
1105
wl_event_loop_add_fd(c->base.input_loop,
1106
xcb_get_file_descriptor(c->conn),
838
1107
WL_EVENT_READABLE,
839
1108
x11_compositor_handle_event, c);
840
1109
wl_event_source_check(c->xcb_source);
842
1111
return &c->base;
1114
x11_input_destroy(c);
1116
x11_compositor_fini_egl(c);
1118
XCloseDisplay(c->dpy);
845
struct weston_compositor *
846
backend_init(struct wl_display *display, char *options);
848
1124
WL_EXPORT struct weston_compositor *
849
backend_init(struct wl_display *display, char *options)
1125
backend_init(struct wl_display *display, int argc, char *argv[],
1126
const char *config_file)
851
int width = 1024, height = 640, fullscreen = 0, count = 1, i;
1128
int width = 1024, height = 640, fullscreen = 0, count = 1;
854
static char * const tokens[] = {
855
"width", "height", "fullscreen", "output-count", NULL
1131
const struct weston_option x11_options[] = {
1132
{ WESTON_OPTION_INTEGER, "width", 0, &width },
1133
{ WESTON_OPTION_INTEGER, "height", 0, &height },
1134
{ WESTON_OPTION_BOOLEAN, "fullscreen", 0, &fullscreen },
1135
{ WESTON_OPTION_INTEGER, "output-count", 0, &count },
1136
{ WESTON_OPTION_BOOLEAN, "no-input", 0, &no_input },
859
while (i = getsubopt(&p, tokens, &value), i != -1) {
862
width = strtol(value, NULL, 0);
865
height = strtol(value, NULL, 0);
871
count = strtol(value, NULL, 0);
1139
parse_options(x11_options, ARRAY_LENGTH(x11_options), argc, argv);
876
1141
return x11_compositor_create(display,
877
width, height, count, fullscreen);
1142
width, height, count, fullscreen,
1144
argc, argv, config_file);