diff options
Diffstat (limited to 'compositor/compositor-x11.c')
| -rw-r--r-- | compositor/compositor-x11.c | 795 |
1 files changed, 0 insertions, 795 deletions
diff --git a/compositor/compositor-x11.c b/compositor/compositor-x11.c deleted file mode 100644 index 4365c0a..0000000 --- a/compositor/compositor-x11.c +++ /dev/null @@ -1,795 +0,0 @@ -/* - * Copyright © 2008-2010 Kristian Høgsberg - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stddef.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <fcntl.h> -#include <unistd.h> -#include <errno.h> -#include <sys/time.h> -#include <linux/input.h> - -#include <xcb/xcb.h> -#include <xcb/dri2.h> -#include <xcb/xfixes.h> - -#define GL_GLEXT_PROTOTYPES -#define EGL_EGLEXT_PROTOTYPES -#include <GLES2/gl2.h> -#include <GLES2/gl2ext.h> -#include <EGL/egl.h> -#include <EGL/eglext.h> - -#include "compositor.h" - -#define ARRAY_SIZE(array) (sizeof(array) / sizeof(array[0])) - -struct x11_compositor { - struct wlsc_compositor base; - - xcb_connection_t *conn; - xcb_screen_t *screen; - xcb_cursor_t null_cursor; - int dri2_major; - int dri2_minor; - struct wl_array keys; - struct wl_event_source *xcb_source; - struct { - xcb_atom_t wm_protocols; - xcb_atom_t wm_normal_hints; - xcb_atom_t wm_size_hints; - xcb_atom_t wm_delete_window; - xcb_atom_t wm_class; - xcb_atom_t net_wm_name; - xcb_atom_t net_wm_icon; - xcb_atom_t string; - xcb_atom_t utf8_string; - xcb_atom_t cardinal; - } atom; -}; - -struct x11_output { - struct wlsc_output base; - - xcb_xfixes_region_t region; - xcb_window_t window; - GLuint rbo; - EGLImageKHR image; - xcb_rectangle_t damage[16]; - int damage_count; -}; - -struct x11_input { - struct wlsc_input_device base; -}; - - -static int -x11_input_create(struct x11_compositor *c) -{ - struct x11_input *input; - - input = malloc(sizeof *input); - if (input == NULL) - return -1; - - memset(input, 0, sizeof *input); - wlsc_input_device_init(&input->base, &c->base); - - c->base.input_device = &input->base.input_device; - - return 0; -} - - -static int -dri2_connect(struct x11_compositor *c) -{ - xcb_xfixes_query_version_reply_t *xfixes_query; - xcb_xfixes_query_version_cookie_t xfixes_query_cookie; - xcb_dri2_query_version_reply_t *dri2_query; - xcb_dri2_query_version_cookie_t dri2_query_cookie; - xcb_dri2_connect_reply_t *connect; - xcb_dri2_connect_cookie_t connect_cookie; - xcb_generic_error_t *error; - char path[256]; - int fd; - - xcb_prefetch_extension_data (c->conn, &xcb_xfixes_id); - xcb_prefetch_extension_data (c->conn, &xcb_dri2_id); - - xfixes_query_cookie = - xcb_xfixes_query_version(c->conn, - XCB_XFIXES_MAJOR_VERSION, - XCB_XFIXES_MINOR_VERSION); - - dri2_query_cookie = - xcb_dri2_query_version (c->conn, - XCB_DRI2_MAJOR_VERSION, - XCB_DRI2_MINOR_VERSION); - - connect_cookie = xcb_dri2_connect_unchecked (c->conn, - c->screen->root, - XCB_DRI2_DRIVER_TYPE_DRI); - - xfixes_query = - xcb_xfixes_query_version_reply (c->conn, - xfixes_query_cookie, &error); - if (xfixes_query == NULL || - error != NULL || xfixes_query->major_version < 2) { - free(error); - return -1; - } - free(xfixes_query); - - dri2_query = - xcb_dri2_query_version_reply (c->conn, - dri2_query_cookie, &error); - if (dri2_query == NULL || error != NULL) { - fprintf(stderr, "DRI2: failed to query version\n"); - free(error); - return EGL_FALSE; - } - c->dri2_major = dri2_query->major_version; - c->dri2_minor = dri2_query->minor_version; - free(dri2_query); - - connect = xcb_dri2_connect_reply (c->conn, - connect_cookie, NULL); - if (connect == NULL || - connect->driver_name_length + connect->device_name_length == 0) { - fprintf(stderr, "DRI2: failed to connect, DRI2 version: %u.%u\n", - c->dri2_major, c->dri2_minor); - return -1; - } - -#ifdef XCB_DRI2_CONNECT_DEVICE_NAME_BROKEN - { - char *driver_name, *device_name; - - driver_name = xcb_dri2_connect_driver_name (connect); - device_name = driver_name + - ((connect->driver_name_length + 3) & ~3); - snprintf(path, sizeof path, "%.*s", - xcb_dri2_connect_device_name_length (connect), - device_name); - } -#else - snprintf(path, sizeof path, "%.*s", - xcb_dri2_connect_device_name_length (connect), - xcb_dri2_connect_device_name (connect)); -#endif - free(connect); - - fd = open(path, O_RDWR); - if (fd < 0) { - fprintf(stderr, - "DRI2: could not open %s (%s)\n", path, strerror(errno)); - return -1; - } - - return wlsc_drm_init(&c->base, fd, path); -} - -static int -dri2_authenticate(struct x11_compositor *c, uint32_t magic) -{ - xcb_dri2_authenticate_reply_t *authenticate; - xcb_dri2_authenticate_cookie_t authenticate_cookie; - - authenticate_cookie = - xcb_dri2_authenticate_unchecked(c->conn, - c->screen->root, magic); - authenticate = - xcb_dri2_authenticate_reply(c->conn, - authenticate_cookie, NULL); - if (authenticate == NULL || !authenticate->authenticated) { - fprintf(stderr, "DRI2: failed to authenticate\n"); - free(authenticate); - return -1; - } - - free(authenticate); - - return 0; -} - -static int -x11_compositor_init_egl(struct x11_compositor *c) -{ - EGLint major, minor; - const char *extensions; - drm_magic_t magic; - static const EGLint context_attribs[] = { - EGL_CONTEXT_CLIENT_VERSION, 2, - EGL_NONE - }; - - if (dri2_connect(c) < 0) - return -1; - - if (drmGetMagic(c->base.drm.fd, &magic)) { - fprintf(stderr, "DRI2: failed to get drm magic\n"); - return -1; - } - - if (dri2_authenticate(c, magic) < 0) - return -1; - - c->base.display = eglGetDRMDisplayMESA(c->base.drm.fd); - if (c->base.display == NULL) { - fprintf(stderr, "failed to create display\n"); - return -1; - } - - if (!eglInitialize(c->base.display, &major, &minor)) { - fprintf(stderr, "failed to initialize display\n"); - return -1; - } - - extensions = eglQueryString(c->base.display, EGL_EXTENSIONS); - if (!strstr(extensions, "EGL_KHR_surfaceless_opengl")) { - fprintf(stderr, "EGL_KHR_surfaceless_opengl not available\n"); - return -1; - } - - if (!eglBindAPI(EGL_OPENGL_ES_API)) { - fprintf(stderr, "failed to bind EGL_OPENGL_ES_API\n"); - return -1; - } - - c->base.context = eglCreateContext(c->base.display, NULL, - EGL_NO_CONTEXT, context_attribs); - if (c->base.context == NULL) { - fprintf(stderr, "failed to create context\n"); - return -1; - } - - if (!eglMakeCurrent(c->base.display, EGL_NO_SURFACE, - EGL_NO_SURFACE, c->base.context)) { - fprintf(stderr, "failed to make context current\n"); - return -1; - } - - return 0; -} - -static void -x11_compositor_present(struct wlsc_compositor *base) -{ - struct x11_compositor *c = (struct x11_compositor *) base; - struct x11_output *output; - xcb_dri2_copy_region_cookie_t cookie; - struct timeval tv; - uint32_t msec; - - glFlush(); - - wl_list_for_each(output, &c->base.output_list, base.link) { - cookie = xcb_dri2_copy_region_unchecked(c->conn, - output->window, - output->region, - XCB_DRI2_ATTACHMENT_BUFFER_FRONT_LEFT, - XCB_DRI2_ATTACHMENT_BUFFER_BACK_LEFT); - free(xcb_dri2_copy_region_reply(c->conn, cookie, NULL)); - } - - gettimeofday(&tv, NULL); - msec = tv.tv_sec * 1000 + tv.tv_usec / 1000; - wlsc_compositor_finish_frame(&c->base, msec); -} - -static void -x11_output_set_wm_protocols(struct x11_output *output) -{ - xcb_atom_t list[1]; - struct x11_compositor *c = - (struct x11_compositor *) output->base.compositor; - - list[0] = c->atom.wm_delete_window; - xcb_change_property (c->conn, - XCB_PROP_MODE_REPLACE, - output->window, - c->atom.wm_protocols, - XCB_ATOM_ATOM, - 32, - ARRAY_SIZE(list), - list); -} - -struct wm_normal_hints { - uint32_t flags; - uint32_t pad[4]; - int32_t min_width, min_height; - int32_t max_width, max_height; - int32_t width_inc, height_inc; - int32_t min_aspect_x, min_aspect_y; - int32_t max_aspect_x, max_aspect_y; - int32_t base_width, base_height; - int32_t win_gravity; -}; - -#define WM_NORMAL_HINTS_MIN_SIZE 16 -#define WM_NORMAL_HINTS_MAX_SIZE 32 - -static void -x11_output_set_icon(struct x11_compositor *c, struct x11_output *output, - const char *filename, int width, int height) -{ - uint32_t *icon, *pixels; - - pixels = wlsc_load_image(filename, width, height); - if (!pixels) - return; - icon = malloc(width * height * 4 + 8); - if (!icon) { - free(pixels); - return; - } - - icon[0] = width; - icon[1] = height; - memcpy(icon + 2, pixels, width * height * 4); - xcb_change_property(c->conn, XCB_PROP_MODE_REPLACE, output->window, - c->atom.net_wm_icon, c->atom.cardinal, 32, - width * height + 2, icon); - free(icon); - free(pixels); -} - -static int -x11_compositor_create_output(struct x11_compositor *c, int width, int height) -{ - static const char name[] = "Wayland Compositor"; - static const char class[] = "wayland-1\0Wayland Compositor"; - struct x11_output *output; - xcb_dri2_dri2_buffer_t *buffers; - xcb_dri2_get_buffers_reply_t *reply; - xcb_dri2_get_buffers_cookie_t cookie; - xcb_screen_iterator_t iter; - xcb_rectangle_t rectangle; - struct wm_normal_hints normal_hints; - unsigned int attachments[] = - { XCB_DRI2_ATTACHMENT_BUFFER_BACK_LEFT}; - uint32_t mask = XCB_CW_EVENT_MASK | XCB_CW_CURSOR; - uint32_t values[2] = { - XCB_EVENT_MASK_KEY_PRESS | - XCB_EVENT_MASK_KEY_RELEASE | - XCB_EVENT_MASK_BUTTON_PRESS | - XCB_EVENT_MASK_BUTTON_RELEASE | - XCB_EVENT_MASK_POINTER_MOTION | - XCB_EVENT_MASK_EXPOSURE | - XCB_EVENT_MASK_STRUCTURE_NOTIFY | - XCB_EVENT_MASK_ENTER_WINDOW | - XCB_EVENT_MASK_LEAVE_WINDOW | - XCB_EVENT_MASK_KEYMAP_STATE | - XCB_EVENT_MASK_FOCUS_CHANGE, - 0 - }; - - EGLint attribs[] = { - EGL_WIDTH, 0, - EGL_HEIGHT, 0, - EGL_DRM_BUFFER_STRIDE_MESA, 0, - EGL_DRM_BUFFER_FORMAT_MESA, EGL_DRM_BUFFER_FORMAT_ARGB32_MESA, - EGL_NONE - }; - - output = malloc(sizeof *output); - if (output == NULL) - return -1; - - memset(output, 0, sizeof *output); - wlsc_output_init(&output->base, &c->base, 0, 0, width, height); - - values[1] = c->null_cursor; - output->window = xcb_generate_id(c->conn); - iter = xcb_setup_roots_iterator(xcb_get_setup(c->conn)); - xcb_create_window(c->conn, - XCB_COPY_FROM_PARENT, - output->window, - iter.data->root, - 0, 0, - width, height, - 0, - XCB_WINDOW_CLASS_INPUT_OUTPUT, - iter.data->root_visual, - mask, values); - - /* Don't resize me. */ - memset(&normal_hints, 0, sizeof normal_hints); - normal_hints.flags = - WM_NORMAL_HINTS_MAX_SIZE | WM_NORMAL_HINTS_MIN_SIZE; - normal_hints.min_width = width; - normal_hints.min_height = height; - normal_hints.max_width = width; - normal_hints.max_height = height; - xcb_change_property (c->conn, XCB_PROP_MODE_REPLACE, output->window, - c->atom.wm_normal_hints, - c->atom.wm_size_hints, 32, - sizeof normal_hints / 4, - (uint8_t *) &normal_hints); - - /* Set window name. Don't bother with non-EWMH WMs. */ - xcb_change_property(c->conn, XCB_PROP_MODE_REPLACE, output->window, - c->atom.net_wm_name, c->atom.utf8_string, 8, - strlen(name), name); - xcb_change_property(c->conn, XCB_PROP_MODE_REPLACE, output->window, - c->atom.wm_class, c->atom.string, 8, - sizeof class, class); - - x11_output_set_icon(c, output, - DATADIR "/wayland/wayland.png", 128, 128); - - xcb_map_window(c->conn, output->window); - - rectangle.x = 0; - rectangle.y = 0; - rectangle.width = width; - rectangle.height = height; - output->region = xcb_generate_id(c->conn); - xcb_xfixes_create_region(c->conn, output->region, 1, &rectangle); - - xcb_dri2_create_drawable (c->conn, output->window); - - x11_output_set_wm_protocols(output); - - cookie = xcb_dri2_get_buffers_unchecked (c->conn, - output->window, - 1, 1, attachments); - reply = xcb_dri2_get_buffers_reply (c->conn, cookie, NULL); - if (reply == NULL) - return -1; - buffers = xcb_dri2_get_buffers_buffers (reply); - if (buffers == NULL) - return -1; - - if (reply->count != 1) { - fprintf(stderr, - "got wrong number of buffers (%d)\n", reply->count); - return -1; - } - - attribs[1] = reply->width; - attribs[3] = reply->height; - attribs[5] = buffers[0].pitch / 4; - output->image = - eglCreateImageKHR(c->base.display, - EGL_NO_CONTEXT, - EGL_DRM_BUFFER_MESA, - (EGLClientBuffer) buffers[0].name, - attribs); - free(reply); - - glGenRenderbuffers(1, &output->rbo); - glBindRenderbuffer(GL_RENDERBUFFER, output->rbo); - - glEGLImageTargetRenderbufferStorageOES(GL_RENDERBUFFER, - output->image); - - glFramebufferRenderbuffer(GL_FRAMEBUFFER, - GL_COLOR_ATTACHMENT0, - GL_RENDERBUFFER, - output->rbo); - - wl_list_insert(c->base.output_list.prev, &output->base.link); - - return 0; -} - -static void -idle_repaint(void *data) -{ - struct x11_output *output = data; - struct x11_compositor *c = - (struct x11_compositor *) output->base.compositor; - xcb_xfixes_region_t region; - xcb_dri2_copy_region_cookie_t cookie; - - if (output->damage_count <= ARRAY_SIZE(output->damage)) { - region = xcb_generate_id(c->conn); - xcb_xfixes_create_region(c->conn, region, - output->damage_count, output->damage); - } else { - region = output->region; - } - - cookie = xcb_dri2_copy_region_unchecked(c->conn, - output->window, - region, - XCB_DRI2_ATTACHMENT_BUFFER_FRONT_LEFT, - XCB_DRI2_ATTACHMENT_BUFFER_BACK_LEFT); - - if (region != output->region) - xcb_xfixes_destroy_region(c->conn, region); - - free(xcb_dri2_copy_region_reply(c->conn, cookie, NULL)); - output->damage_count = 0; -} - -static struct x11_output * -x11_compositor_find_output(struct x11_compositor *c, xcb_window_t window) -{ - struct x11_output *output; - - wl_list_for_each(output, &c->base.output_list, base.link) { - if (output->window == window) - return output; - } - - return NULL; -} - -static void -x11_compositor_handle_event(int fd, uint32_t mask, void *data) -{ - struct x11_compositor *c = data; - struct x11_output *output; - xcb_generic_event_t *event; - struct wl_event_loop *loop; - xcb_client_message_event_t *client_message; - xcb_motion_notify_event_t *motion_notify; - xcb_enter_notify_event_t *enter_notify; - xcb_key_press_event_t *key_press; - xcb_button_press_event_t *button_press; - xcb_keymap_notify_event_t *keymap_notify; - xcb_focus_in_event_t *focus_in; - xcb_expose_event_t *expose; - xcb_rectangle_t *r; - xcb_atom_t atom; - uint32_t *k; - int i, set; - - loop = wl_display_get_event_loop(c->base.wl_display); - while (event = xcb_poll_for_event (c->conn), event != NULL) { - switch (event->response_type & ~0x80) { - - case XCB_KEY_PRESS: - key_press = (xcb_key_press_event_t *) event; - notify_key(c->base.input_device, - key_press->time, key_press->detail - 8, 1); - break; - case XCB_KEY_RELEASE: - key_press = (xcb_key_press_event_t *) event; - notify_key(c->base.input_device, - key_press->time, key_press->detail - 8, 0); - break; - case XCB_BUTTON_PRESS: - button_press = (xcb_button_press_event_t *) event; - notify_button(c->base.input_device, - button_press->time, - button_press->detail + BTN_LEFT - 1, 1); - break; - case XCB_BUTTON_RELEASE: - button_press = (xcb_button_press_event_t *) event; - notify_button(c->base.input_device, - button_press->time, - button_press->detail + BTN_LEFT - 1, 0); - break; - - case XCB_MOTION_NOTIFY: - motion_notify = (xcb_motion_notify_event_t *) event; - notify_motion(c->base.input_device, - motion_notify->time, - motion_notify->event_x, - motion_notify->event_y); - break; - - case XCB_EXPOSE: - expose = (xcb_expose_event_t *) event; - output = x11_compositor_find_output(c, expose->window); - if (output->damage_count == 0) - wl_event_loop_add_idle(loop, - idle_repaint, output); - - r = &output->damage[output->damage_count++]; - if (output->damage_count > 16) - break; - r->x = expose->x; - r->y = expose->y; - r->width = expose->width; - r->height = expose->height; - break; - - case XCB_ENTER_NOTIFY: - enter_notify = (xcb_enter_notify_event_t *) event; - if (enter_notify->state >= Button1Mask) - break; - output = x11_compositor_find_output(c, enter_notify->event); - notify_pointer_focus(c->base.input_device, - enter_notify->time, - &output->base, - enter_notify->event_x, - enter_notify->event_y); - break; - - case XCB_LEAVE_NOTIFY: - enter_notify = (xcb_enter_notify_event_t *) event; - if (enter_notify->state >= Button1Mask) - break; - notify_pointer_focus(c->base.input_device, - enter_notify->time, - NULL, - enter_notify->event_x, - enter_notify->event_y); - break; - - case XCB_CLIENT_MESSAGE: - client_message = (xcb_client_message_event_t *) event; - atom = client_message->data.data32[0]; - if (atom == c->atom.wm_delete_window) - wl_display_terminate(c->base.wl_display); - break; - - case XCB_FOCUS_IN: - focus_in = (xcb_focus_in_event_t *) event; - if (focus_in->mode == XCB_NOTIFY_MODE_WHILE_GRABBED) - break; - - output = x11_compositor_find_output(c, focus_in->event); - notify_keyboard_focus(c->base.input_device, - get_time(), - &output->base, &c->keys); - break; - - case XCB_FOCUS_OUT: - focus_in = (xcb_focus_in_event_t *) event; - if (focus_in->mode == XCB_NOTIFY_MODE_WHILE_GRABBED) - break; - notify_keyboard_focus(c->base.input_device, - get_time(), NULL, NULL); - break; - - case XCB_KEYMAP_NOTIFY: - keymap_notify = (xcb_keymap_notify_event_t *) event; - c->keys.size = 0; - for (i = 0; i < ARRAY_LENGTH(keymap_notify->keys) * 8; i++) { - set = keymap_notify->keys[i >> 3] & - (1 << (i & 7)); - if (set) { - k = wl_array_add(&c->keys, sizeof *k); - *k = i; - } - } - break; - default: - break; - } - - free (event); - } -} - -#define F(field) offsetof(struct x11_compositor, field) - -static void -x11_compositor_get_resources(struct x11_compositor *c) -{ - static const struct { const char *name; int offset; } atoms[] = { - { "WM_PROTOCOLS", F(atom.wm_protocols) }, - { "WM_NORMAL_HINTS", F(atom.wm_normal_hints) }, - { "WM_SIZE_HINTS", F(atom.wm_size_hints) }, - { "WM_DELETE_WINDOW", F(atom.wm_delete_window) }, - { "WM_CLASS", F(atom.wm_class) }, - { "_NET_WM_NAME", F(atom.net_wm_name) }, - { "_NET_WM_ICON", F(atom.net_wm_icon) }, - { "STRING", F(atom.string) }, - { "UTF8_STRING", F(atom.utf8_string) }, - { "CARDINAL", F(atom.cardinal) }, - }; - - xcb_intern_atom_cookie_t cookies[ARRAY_SIZE(atoms)]; - xcb_intern_atom_reply_t *reply; - xcb_pixmap_t pixmap; - xcb_gc_t gc; - int i; - uint8_t data[] = { 0, 0, 0, 0 }; - - for (i = 0; i < ARRAY_SIZE(atoms); i++) - cookies[i] = xcb_intern_atom (c->conn, 0, - strlen(atoms[i].name), - atoms[i].name); - - for (i = 0; i < ARRAY_SIZE(atoms); i++) { - reply = xcb_intern_atom_reply (c->conn, cookies[i], NULL); - *(xcb_atom_t *) ((char *) c + atoms[i].offset) = reply->atom; - free(reply); - } - - pixmap = xcb_generate_id(c->conn); - gc = xcb_generate_id(c->conn); - xcb_create_pixmap(c->conn, 1, pixmap, c->screen->root, 1, 1); - xcb_create_gc(c->conn, gc, pixmap, 0, NULL); - xcb_put_image(c->conn, XCB_IMAGE_FORMAT_XY_PIXMAP, - pixmap, gc, 1, 1, 0, 0, 0, 32, sizeof data, data); - c->null_cursor = xcb_generate_id(c->conn); - xcb_create_cursor (c->conn, c->null_cursor, - pixmap, pixmap, 0, 0, 0, 0, 0, 0, 1, 1); - xcb_free_gc(c->conn, gc); - xcb_free_pixmap(c->conn, pixmap); -} - -static int -x11_authenticate(struct wlsc_compositor *c, uint32_t id) -{ - return dri2_authenticate((struct x11_compositor *) c, id); -} - -static void -x11_destroy(struct wlsc_compositor *ec) -{ - free(ec); -} - -struct wlsc_compositor * -x11_compositor_create(struct wl_display *display, int width, int height) -{ - struct x11_compositor *c; - struct wl_event_loop *loop; - xcb_screen_iterator_t s; - - c = malloc(sizeof *c); - if (c == NULL) - return NULL; - - memset(c, 0, sizeof *c); - c->conn = xcb_connect(0, 0); - - if (xcb_connection_has_error(c->conn)) - return NULL; - - s = xcb_setup_roots_iterator(xcb_get_setup(c->conn)); - c->screen = s.data; - wl_array_init(&c->keys); - - x11_compositor_get_resources(c); - - c->base.wl_display = display; - if (x11_compositor_init_egl(c) < 0) - return NULL; - - c->base.destroy = x11_destroy; - c->base.authenticate = x11_authenticate; - c->base.present = x11_compositor_present; - c->base.create_buffer = wlsc_drm_buffer_create; - - /* Can't init base class until we have a current egl context */ - if (wlsc_compositor_init(&c->base, display) < 0) - return NULL; - - if (x11_compositor_create_output(c, width, height) < 0) - return NULL; - - if (x11_input_create(c) < 0) - return NULL; - - loop = wl_display_get_event_loop(c->base.wl_display); - - c->xcb_source = - wl_event_loop_add_fd(loop, xcb_get_file_descriptor(c->conn), - WL_EVENT_READABLE, - x11_compositor_handle_event, c); - - return &c->base; -} |
