Пример #1
0
Файл: drm.c Проект: UIKit0/wlc
static bool
create_fb(struct gbm_surface *surface, struct drm_fb *fb)
{
    assert(surface && fb);

    if (!gbm.api.gbm_surface_has_free_buffers(surface))
        goto no_buffers;

    if (!(fb->bo = gbm.api.gbm_surface_lock_front_buffer(surface)))
        goto failed_to_lock;

    uint32_t width = gbm.api.gbm_bo_get_width(fb->bo);
    uint32_t height = gbm.api.gbm_bo_get_height(fb->bo);
    uint32_t handle = gbm.api.gbm_bo_get_handle(fb->bo).u32;
    uint32_t stride = gbm.api.gbm_bo_get_stride(fb->bo);

    if (drm.api.drmModeAddFB(drm.fd, width, height, 24, 32, stride, handle, &fb->fd))
        goto failed_to_create_fb;

    fb->stride = stride;
    return true;

no_buffers:
    wlc_log(WLC_LOG_WARN, "gbm is out of buffers");
    goto fail;
failed_to_lock:
    wlc_log(WLC_LOG_WARN, "Failed to lock front buffer");
    goto fail;
failed_to_create_fb:
    wlc_log(WLC_LOG_WARN, "Failed to create fb");
fail:
    release_fb(surface, fb);
    return false;
}
Пример #2
0
Файл: x11.c Проект: snells/wlc
static bool
x11_xcb_load(void)
{
   const char *lib = "libX11-xcb.so", *func = NULL;

   if (!(x11.api.x11_xcb_handle = dlopen(lib, RTLD_LAZY))) {
      wlc_log(WLC_LOG_WARN, "%s", dlerror());
      return false;
   }

#define load(x) (x11.api.x = dlsym(x11.api.x11_xcb_handle, (func = #x)))

   if (!load(XGetXCBConnection))
      goto function_pointer_exception;
   if (!load(XSetEventQueueOwner))
      goto function_pointer_exception;

#undef load

   return true;

function_pointer_exception:
   wlc_log(WLC_LOG_WARN, "Could not load function '%s' from '%s'", func, lib);
   return false;
}
Пример #3
0
Файл: x11.c Проект: snells/wlc
static bool
x11_load(void)
{
   const char *lib = "libX11.so", *func = NULL;

   if (!(x11.api.x11_handle = dlopen(lib, RTLD_LAZY))) {
      wlc_log(WLC_LOG_WARN, "%s", dlerror());
      return false;
   }

#define load(x) (x11.api.x = dlsym(x11.api.x11_handle, (func = #x)))

   if (!load(XOpenDisplay))
      goto function_pointer_exception;
   if (!load(XCloseDisplay))
      goto function_pointer_exception;

#undef load

   return true;

function_pointer_exception:
   wlc_log(WLC_LOG_WARN, "Could not load function '%s' from '%s'", func, lib);
   return false;
}
Пример #4
0
Файл: x11.c Проект: snells/wlc
static bool
xcb_xkb_load(void)
{
   const char *lib = "libxcb-xkb.so", *func = NULL;

   if (!(x11.api.xcb_xkb_handle = dlopen(lib, RTLD_LAZY))) {
      wlc_log(WLC_LOG_WARN, "%s", dlerror());
      return false;
   }

#define load(x) (x11.api.x = dlsym(x11.api.xcb_xkb_handle, (func = #x)))

   if (!load(xcb_xkb_per_client_flags))
      goto function_pointer_exception;
   if (!load(xcb_xkb_per_client_flags_reply))
      goto function_pointer_exception;
   if (!load(xcb_xkb_select_events_checked))
      goto function_pointer_exception;
   if (!load(xcb_xkb_use_extension))
      goto function_pointer_exception;
   if (!load(xcb_xkb_use_extension_reply))
      goto function_pointer_exception;
   if (!load(xcb_xkb_id))
      goto function_pointer_exception;

#undef load

   return true;

function_pointer_exception:
   wlc_log(WLC_LOG_WARN, "Could not load function '%s' from '%s'", func, lib);
   return false;
}
Пример #5
0
Файл: wlc.c Проект: UIKit0/wlc
static void
backtrace(int signal)
{
   (void)signal;

   if (clearenv() != 0)
      exit(EXIT_FAILURE);

   /* GDB */
#if defined(__linux__) || defined(__APPLE__)
   pid_t child_pid = fork();

#if HAS_YAMA_PRCTL
   /* tell yama that we allow our child_pid to trace our process */
   if (child_pid > 0) {
      if (!prctl(PR_GET_DUMPABLE)) {
         wlc_log(WLC_LOG_WARN, "Compositor binary is suid/sgid, most likely since you are running from TTY.");
         wlc_log(WLC_LOG_WARN, "Kernel ptracing security policy does not allow attaching to suid/sgid processes.");
         wlc_log(WLC_LOG_WARN, "If you don't get backtrace below, try `setcap cap_sys_ptrace=eip gdb` temporarily.");
      }
      prctl(PR_SET_DUMPABLE, 1);
      prctl(PR_SET_PTRACER, child_pid);
   }
#endif

   if (child_pid < 0) {
      wlc_log(WLC_LOG_WARN, "Fork failed for gdb backtrace");
   } else if (child_pid == 0) {
      /*
       * NOTE: gdb-7.8 does not seem to work with this,
       *       either downgrade to 7.7 or use gdb from master.
       */

      /* sed -n '/bar/h;/bar/!H;$!b;x;p' (another way, if problems) */
      char buf[255];
      const int fd = fileno(wlc_get_log_file());
      snprintf(buf, sizeof(buf) - 1, "gdb -p %d -n -batch -ex bt 2>/dev/null | sed -n '/<signal handler/{n;x;b};H;${x;p}' 1>&%d", getppid(), fd);
      execl("/bin/sh", "/bin/sh", "-c", buf, NULL);
      wlc_log(WLC_LOG_ERROR, "Failed to launch gdb for backtrace");
      _exit(EXIT_FAILURE);
   } else {
      waitpid(child_pid, NULL, 0);
   }
#endif

   /* SIGABRT || SIGSEGV */
   exit(EXIT_FAILURE);
}
Пример #6
0
Файл: wlc.c Проект: UIKit0/wlc
void
wlc_cleanup(void)
{
   if (wlc.display) {
      wlc_log(WLC_LOG_INFO, "Cleanup wlc");

      // fd process never allocates display
      wlc_compositor_release(&wlc.compositor);
      wl_list_remove(&compositor_listener.link);
      wlc_xwayland_terminate();
      wlc_input_terminate();
      wlc_udev_terminate();
      wlc_fd_terminate();
   }

   // however if main process crashed, fd process does
   // know enough about tty to reset it.
   wlc_tty_terminate();

   if (wlc.display)
      wl_display_destroy(wlc.display);

   // reset te struct, but keep the wlc log state
   FILE *f = wlc.log_file;
   int cached_tm_mday = wlc.cached_tm_mday;
   memset(&wlc, 0, sizeof(wlc));
   wlc_set_log_file(f);
   wlc.cached_tm_mday = cached_tm_mday;
}
Пример #7
0
Файл: wlc.c Проект: UIKit0/wlc
static void
fpehandler(int signal)
{
   (void)signal;
   wlc_log(WLC_LOG_INFO, "SIGFPE signal received");
   abort();
}
Пример #8
0
void
wlc_cleanup(void)
{
   if (wlc.display) {
      wlc_log(WLC_LOG_INFO, "Cleanup wlc");

      // fd process never allocates display
      wlc_compositor_release(&wlc.compositor);
      wl_list_remove(&compositor_listener.link);
      wlc_xwayland_terminate();
      wlc_resources_terminate();
      wlc_input_terminate();
      wlc_udev_terminate();
      wlc_fd_terminate();
   }

   // however if main process crashed, fd process does
   // know enough about tty to reset it.
   wlc_tty_terminate();

   if (wlc.display)
      wl_display_destroy(wlc.display);

   memset(&wlc, 0, sizeof(wlc));
}
Пример #9
0
static bool
surface_attach(struct ctx *context, struct wlc_context *bound, struct wlc_surface *surface, struct wlc_buffer *buffer)
{
   assert(context && bound && surface);

   struct wl_resource *wl_buffer;
   if (!buffer || !(wl_buffer = convert_to_wl_resource(buffer, "buffer"))) {
      surface_destroy(context, bound, surface);
      return true;
   }

   EGLint format;
   bool attached = false;

   struct wl_shm_buffer *shm_buffer = wl_shm_buffer_get(wl_buffer);
   if (shm_buffer) {
      attached = shm_attach(surface, buffer, shm_buffer);
   } else if (wlc_context_query_buffer(bound, (void*)wl_buffer, EGL_TEXTURE_FORMAT, &format)) {
      attached = egl_attach(context, bound, surface, buffer, format);
   } else {
      /* unknown buffer */
      wlc_log(WLC_LOG_WARN, "Unknown buffer");
   }

   if (attached)
      wlc_dlog(WLC_DBG_RENDER, "-> Attached surface (%" PRIuWLC ") with buffer of size (%ux%u)", convert_to_wlc_resource(surface), buffer->size.w, buffer->size.h);

   return attached;
}
Пример #10
0
Файл: drm.c Проект: UIKit0/wlc
static bool
drm_load(void)
{
    const char *lib = "libdrm.so", *func = NULL;

    if (!(drm.api.handle = dlopen(lib, RTLD_LAZY))) {
        wlc_log(WLC_LOG_WARN, "%s", dlerror());
        return false;
    }

#define load(x) (drm.api.x = dlsym(drm.api.handle, (func = #x)))

    if (!load(drmIoctl))
        goto function_pointer_exception;
    if (!load(drmModeAddFB))
        goto function_pointer_exception;
    if (!load(drmModeRmFB))
        goto function_pointer_exception;
    if (!load(drmModePageFlip))
        goto function_pointer_exception;
    if (!load(drmModeSetCrtc))
        goto function_pointer_exception;
    if (!load(drmHandleEvent))
        goto function_pointer_exception;
    if (!load(drmModeGetResources))
        goto function_pointer_exception;
    if (!load(drmModeGetCrtc))
        goto function_pointer_exception;
    if (!load(drmModeFreeCrtc))
        goto function_pointer_exception;
    if (!load(drmModeGetConnector))
        goto function_pointer_exception;
    if (!load(drmModeFreeConnector))
        goto function_pointer_exception;
    if (!load(drmModeGetEncoder))
        goto function_pointer_exception;
    if (!load(drmModeFreeEncoder))
        goto function_pointer_exception;

#undef load

    return true;

function_pointer_exception:
    wlc_log(WLC_LOG_WARN, "Could not load function '%s' from '%s'", func, lib);
    return false;
}
Пример #11
0
static void
sigusr_handler(int signal_number)
{
   assert(signal_number == SIGUSR1);
   wlc_log(WLC_LOG_INFO, "Xwayland started (DISPLAY %s)", xserver.display_name);
   sigaction(signal_number, &xserver.old_sigusr1, NULL);
   setenv("DISPLAY", xserver.display_name, true);
   wl_signal_emit(&wlc_system_signals()->xwayland, &(bool){true});
Пример #12
0
Файл: gles2.c Проект: UIKit0/wlc
static
void gl_call(const char *func, uint32_t line, const char *glfunc)
{
   GLenum error;
   if ((error = gl.api.glGetError()) == GL_NO_ERROR)
      return;

   wlc_log(WLC_LOG_ERROR, "gles2: function %s at line %u: %s == %s", func, line, glfunc, gl_error_string(error));
}
Пример #13
0
Файл: wlc.c Проект: UIKit0/wlc
WLC_API void
wlc_terminate(void)
{
   if (!wlc.display)
      return;

   wlc_log(WLC_LOG_INFO, "Terminating wlc...");
   wl_signal_emit(&wlc.signals.terminate, NULL);
}
Пример #14
0
static void
egl_call(const char *func, uint32_t line, const char *eglfunc)
{
   EGLint error;
   if ((error = eglGetError()) == EGL_SUCCESS)
      return;

   wlc_log(WLC_LOG_ERROR, "egl: function %s at line %u: %s\n%s", func, line, eglfunc, egl_error_string(error));
}
Пример #15
0
Файл: drm.c Проект: UIKit0/wlc
static bool
gbm_load(void)
{
    const char *lib = "libgbm.so", *func = NULL;

    if (!(gbm.api.handle = dlopen(lib, RTLD_LAZY))) {
        wlc_log(WLC_LOG_WARN, "%s", dlerror());
        return false;
    }

#define load(x) (gbm.api.x = dlsym(gbm.api.handle, (func = #x)))

    if (!load(gbm_create_device))
        goto function_pointer_exception;
    if (!load(gbm_device_destroy))
        goto function_pointer_exception;
    if (!load(gbm_surface_create))
        goto function_pointer_exception;
    if (!load(gbm_surface_destroy))
        goto function_pointer_exception;
    if (!load(gbm_bo_get_handle))
        goto function_pointer_exception;
    if (!load(gbm_bo_get_width))
        goto function_pointer_exception;
    if (!load(gbm_bo_get_height))
        goto function_pointer_exception;
    if (!load(gbm_bo_get_stride))
        goto function_pointer_exception;
    if (!load(gbm_surface_has_free_buffers))
        goto function_pointer_exception;
    if (!load(gbm_surface_lock_front_buffer))
        goto function_pointer_exception;
    if (!load(gbm_surface_release_buffer))
        goto function_pointer_exception;

#undef load

    return true;

function_pointer_exception:
    wlc_log(WLC_LOG_WARN, "Could not load function '%s' from '%s'", func, lib);
    return false;
}
Пример #16
0
Файл: udev.c Проект: Azarn/wlc
static int
udev_event(int fd, uint32_t mask, void *data)
{
   (void)fd, (void)mask;
   struct udev *udev = data;
   struct udev_device *device;

   if (!(device = udev_monitor_receive_device(udev->monitor)))
      return 0;

   wlc_log(WLC_LOG_INFO, "udev: got device %s", udev_device_get_sysname(device));

   // FIXME: pass correct drm id
   if (is_hotplug(0, device)) {
      wlc_log(WLC_LOG_INFO, "udev: hotplug");
      struct wlc_output_event ev = { .type = WLC_OUTPUT_EVENT_UPDATE };
      wl_signal_emit(&wlc_system_signals()->output, &ev);
      goto out;
   }
Пример #17
0
static bool
xcb_call(const char *func, uint32_t line, xcb_void_cookie_t cookie)
{
   xcb_generic_error_t *error;
   if (!(error = xcb_request_check(x11.connection, cookie)))
      return true;

   wlc_log(WLC_LOG_ERROR, "xwm: function %s at line %u x11 error code %d", func, line, error->error_code);
   free(error);
   return false;
}
Пример #18
0
Файл: drm.c Проект: UIKit0/wlc
static bool
page_flip(struct wlc_backend_surface *bsurface)
{
    assert(bsurface && bsurface->internal);
    struct drm_surface *dsurface = bsurface->internal;
    assert(!dsurface->flipping);
    struct drm_fb *fb = &dsurface->fb[dsurface->index];
    release_fb(dsurface->surface, fb);

    struct wlc_output *o;
    except((o = wl_container_of(bsurface, o, bsurface)));

    if (!create_fb(dsurface->surface, fb))
        return false;

    if (fb->stride != dsurface->stride) {
        if (drm.api.drmModeSetCrtc(drm.fd, dsurface->crtc->crtc_id, fb->fd, 0, 0, &dsurface->connector->connector_id, 1, &dsurface->connector->modes[o->active.mode]))
            goto set_crtc_fail;

        dsurface->stride = fb->stride;
    }

    if (drm.api.drmModePageFlip(drm.fd, dsurface->crtc->crtc_id, fb->fd, DRM_MODE_PAGE_FLIP_EVENT, bsurface))
        goto failed_to_page_flip;

    dsurface->flipping = true;
    return true;

set_crtc_fail:
    wlc_log(WLC_LOG_WARN, "Failed to set mode: %m");
    goto fail;
failed_to_page_flip:
    wlc_log(WLC_LOG_WARN, "Failed to page flip: %m");
fail:
    release_fb(dsurface->surface, fb);
    return false;
}
Пример #19
0
Файл: wlc.c Проект: UIKit0/wlc
void
wlc_set_active(bool active)
{
   if (active == wlc.active)
      return;

   wlc.active = active;
   struct wlc_activate_event ev = { .active = active, .vt = 0 };
   wl_signal_emit(&wlc.signals.activate, &ev);
   wlc_log(WLC_LOG_INFO, (wlc.active ? "become active" : "deactive"));
}

bool
wlc_get_active(void)
{
   return wlc.active;
}

const struct wlc_interface*
wlc_interface(void)
{
   return &wlc.interface;
}

struct wlc_system_signals*
wlc_system_signals(void)
{
   return &wlc.signals;
}

struct wl_event_loop*
wlc_event_loop(void)
{
   return wl_display_get_event_loop(wlc.display);
}

struct wl_display*
wlc_display(void)
{
   return wlc.display;
}

static void
compositor_event(struct wl_listener *listener, void *data)
{
   (void)listener, (void)data;
   // this event is currently only used for knowing when compositor died
   wl_display_terminate(wlc.display);
}
Пример #20
0
static int
open_socket(struct sockaddr_un *addr, size_t path_size)
{
   int fd;
   socklen_t size = offsetof(struct sockaddr_un, sun_path) + path_size + 1;

   if ((fd = socket(PF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC, 0)) < 0)
      goto socket_fail;

   /* Unlink the socket location in case it was being used by a process which left around a stale lockfile. */
   unlink(addr->sun_path);

   if (bind(fd, (struct sockaddr*)addr, size) < 0)
      goto bind_fail;

   if (listen(fd, 1) < 0)
      goto listen_fail;

   return fd;

socket_fail:
   wlc_log(WLC_LOG_WARN, "Failed to create socket: %s", addr->sun_path);
   goto fail;
bind_fail:
   wlc_log(WLC_LOG_WARN, "Failed to bind socket: %s", addr->sun_path);
   goto fail;
listen_fail:
   wlc_log(WLC_LOG_WARN, "Failed to listen to socket");
   if (addr->sun_path[0])
      unlink(addr->sun_path);
   goto fail;
fail:
   if (fd >= 0)
      close(fd);
   return -1;
}
Пример #21
0
Файл: wlc.c Проект: UIKit0/wlc
WLC_API void
wlc_exec(const char *bin, char *const args[])
{
   assert(bin);

   if (chck_cstr_is_empty(bin))
      return;

   pid_t p;
   if ((p = fork()) == 0) {
      setsid();
      freopen("/dev/null", "w", stdout);
      freopen("/dev/null", "w", stderr);
      execvp(bin, args);
      _exit(EXIT_FAILURE);
   } else if (p < 0) {
      wlc_log(WLC_LOG_ERROR, "Failed to fork for '%s'", bin);
   }
}
Пример #22
0
Файл: drm.c Проект: UIKit0/wlc
static void
surface_release(struct wlc_backend_surface *bsurface)
{
    struct drm_surface *dsurface = bsurface->internal;
    struct drm_fb *fb = &dsurface->fb[dsurface->index];
    release_fb(dsurface->surface, fb);

    drm.api.drmModeSetCrtc(drm.fd, dsurface->crtc->crtc_id, dsurface->crtc->buffer_id, dsurface->crtc->x, dsurface->crtc->y, &dsurface->connector->connector_id, 1, &dsurface->crtc->mode);

    if (dsurface->crtc)
        drm.api.drmModeFreeCrtc(dsurface->crtc);

    if (dsurface->surface)
        gbm.api.gbm_surface_destroy(dsurface->surface);

    if (dsurface->encoder)
        drm.api.drmModeFreeEncoder(dsurface->encoder);

    if (dsurface->connector)
        drm.api.drmModeFreeConnector(dsurface->connector);

    wlc_log(WLC_LOG_INFO, "Released drm surface (%p)", bsurface);
}
Пример #23
0
Файл: render.c Проект: Azarn/wlc
bool
wlc_render(struct wlc_render *render, struct wlc_context *context)
{
   assert(render && context);
   memset(render, 0, sizeof(struct wlc_render));

   if (!wlc_context_bind(context))
      return NULL;

   void* (*constructor[])(struct wlc_render_api*) = {
      wlc_gles2,
      NULL
   };

   for (uint32_t i = 0; constructor[i]; ++i) {
      if ((render->render = constructor[i](&render->api)))
         return true;
   }

   wlc_log(WLC_LOG_WARN, "Could not initialize any rendering backend");
   wlc_render_release(render, context);
   return false;
}
Пример #24
0
Файл: gles2.c Проект: UIKit0/wlc
static GLuint
create_shader(const char *source, GLenum shader_type)
{
   assert(source);

   GLuint shader = gl.api.glCreateShader(shader_type);
   assert(shader != 0);

   GL_CALL(gl.api.glShaderSource(shader, 1, (const char **)&source, NULL));
   GL_CALL(gl.api.glCompileShader(shader));

   GLint status;
   GL_CALL(gl.api.glGetShaderiv(shader, GL_COMPILE_STATUS, &status));
   if (!status) {
      GLsizei len;
      char log[1024];
      GL_CALL(gl.api.glGetShaderInfoLog(shader, sizeof(log), &len, log));
      wlc_log(WLC_LOG_ERROR, "Compiling %s: %*s\n", (shader_type == GL_VERTEX_SHADER ? "vertex" : "fragment"), len, log);
      abort();
   }

   return shader;
}
Пример #25
0
Файл: gles2.c Проект: UIKit0/wlc
static struct ctx*
create_context(void)
{
   const char *vert_shader =
      "#version 100\n"
      "precision mediump float;\n"
      "uniform vec2 resolution;\n"
      "mat4 ortho = mat4("
      "  2.0/resolution.x,         0,          0, 0,"
      "          0,        -2.0/resolution.y,  0, 0,"
      "          0,                0,         -1, 0,"
      "         -1,                1,          0, 1"
      ");\n"
      "attribute vec4 pos;\n"
      "attribute vec2 uv;\n"
      "varying vec2 v_uv;\n"
      "void main() {\n"
      "  gl_Position = ortho * pos;\n"
      "  v_uv = uv;\n"
      "}\n";

   const char *frag_shader_dummy =
      "#version 100\n"
      "precision mediump float;\n"
      "void main() {\n"
      "  gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n"
      "}\n";

   const char *frag_shader_cursor =
      "#version 100\n"
      "precision highp float;\n"
      "uniform sampler2D texture0;\n"
      "varying vec2 v_uv;\n"
      "void main() {\n"
      "  vec4 palette[3];\n"
      "  palette[0] = vec4(0.0, 0.0, 0.0, 1.0);\n"
      "  palette[1] = vec4(1.0, 1.0, 1.0, 1.0);\n"
      "  palette[2] = vec4(0.0, 0.0, 0.0, 0.0);\n"
      "  gl_FragColor = palette[int(texture2D(texture0, v_uv).r * 256.0)];\n"
      "}\n";

   const char *frag_shader_bg =
      "#version 100\n"
      "precision mediump float;\n"
      "uniform float time;\n"
      "uniform vec2 resolution;\n"
      "varying vec2 v_uv;\n"
      "#define M_PI 3.1415926535897932384626433832795\n"
      "float impulse(float x, float k) {\n"
      "  float h = k * x;\n"
      "  return h * exp(1.0 - h);\n"
      "}\n"
      "void main() {\n"
      "  vec3 color = vec3(0.0);\n"
      "  vec2 pos = (v_uv * 4.0 - 2.0);\n"
      "  float frame = time * M_PI * 10.0;\n"
      "  float f = impulse(0.01, sin(frame) + 1.0) + 0.25;\n"
      "  color += vec3(0.15, 0.3, 0.35) * (1.0 / distance(vec2(1.0, 0.0), pos) * f);\n"
      "  for (int i = 0; i < 3; ++i) {\n"
      "     float t = frame + (float(i) * 1.8);\n"
      "     color += vec3(0.15, 0.18, 0.15) * float(i + 1) * (1.0 / distance(vec2(sin(t * 0.8) * 0.5 + 1.0, cos(t) * 0.5), pos) * 0.09);\n"
      "  }\n"
      "  gl_FragColor = vec4(color, 1.0);\n"
      "}\n";

   const char *frag_shader_rgb =
      "#version 100\n"
      "precision mediump float;\n"
      "uniform sampler2D texture0;\n"
      "uniform float dim;\n"
      "varying vec2 v_uv;\n"
      "void main() {\n"
      "  gl_FragColor = vec4(texture2D(texture0, v_uv).rgb * dim, 1.0);\n"
      "}\n";

   const char *frag_shader_rgba =
      "#version 100\n"
      "precision mediump float;\n"
      "uniform sampler2D texture0;\n"
      "uniform float dim;\n"
      "varying vec2 v_uv;\n"
      "void main() {\n"
      "  vec4 col = texture2D(texture0, v_uv);\n"
      "  gl_FragColor = vec4(col.rgb * dim, col.a);\n"
      "}\n";

   const char *frag_shader_egl =
      "#version 100\n"
      "#extension GL_OES_EGL_image_external : require\n"
      "precision mediump float;\n"
      "uniform samplerExternalOES texture0;\n"
      "uniform float dim;\n"
      "varying vec2 v_uv;\n"
      "void main()\n"
      "{\n"
      "  vec4 col = texture2D(texture0, v_uv);\n"
      "  gl_FragColor = vec4(col.rgb * dim, col.a)\n;"
      "}\n";

#define FRAGMENT_CONVERT_YUV                                        \
      "  y *= dim;\n"                                               \
      "  u *= dim;\n"                                               \
      "  v *= dim;\n"                                               \
      "  gl_FragColor.r = y + 1.59602678 * v;\n"                    \
      "  gl_FragColor.g = y - 0.39176229 * u - 0.81296764 * v;\n"   \
      "  gl_FragColor.b = y + 2.01723214 * u;\n"                    \
      "  gl_FragColor.a = 1.0;\n"

   const char *frag_shader_y_uv =
      "#version 100\n"
      "precision mediump float;\n"
      "uniform sampler2D texture0;\n"
      "uniform sampler2D texture1;\n"
      "uniform float dim;\n"
      "varying vec2 v_uv;\n"
      "void main() {\n"
      "  float y = 1.16438356 * (texture2D(texture0, v_uv).x - 0.0625);\n"
      "  float u = texture2D(texture1, v_uv).r - 0.5;\n"
      "  float v = texture2D(texture1, v_uv).g - 0.5;\n"
      FRAGMENT_CONVERT_YUV
      "}\n";

   const char *frag_shader_y_u_v =
      "#version 100\n"
      "precision mediump float;\n"
      "uniform sampler2D texture0;\n"
      "uniform sampler2D texture1;\n"
      "uniform sampler2D texture2;\n"
      "uniform float dim;\n"
      "varying vec2 v_uv;\n"
      "void main() {\n"
      "  float y = 1.16438356 * (texture2D(texture0, v_uv).x - 0.0625);\n"
      "  float u = texture2D(texture1, v_uv).x - 0.5;\n"
      "  float v = texture2D(texture2, v_uv).x - 0.5;\n"
      FRAGMENT_CONVERT_YUV
      "}\n";

   const char *frag_shader_y_xuxv =
      "#version 100\n"
      "precision mediump float;\n"
      "uniform sampler2D texture0;\n"
      "uniform sampler2D texture1;\n"
      "uniform float dim;\n"
      "varying vec2 v_uv;\n"
      "void main() {\n"
      "  float y = 1.16438356 * (texture2D(texture0, v_uv).x - 0.0625);\n"
      "  float u = texture2D(texture1, v_uv).g - 0.5;\n"
      "  float v = texture2D(texture1, v_uv).a - 0.5;\n"
      FRAGMENT_CONVERT_YUV
      "}\n";

   struct ctx *context;
   if (!(context = calloc(1, sizeof(struct ctx))))
      return NULL;

   const char *str;
   str = (const char*)GL_CALL(gl.api.glGetString(GL_VERSION));
   wlc_log(WLC_LOG_INFO, "GL version: %s", str ? str : "(null)");
   str = (const char*)GL_CALL(gl.api.glGetString(GL_VENDOR));
   wlc_log(WLC_LOG_INFO, "GL vendor: %s", str ? str : "(null)");

   context->extensions = (const char*)GL_CALL(gl.api.glGetString(GL_EXTENSIONS));

   if (has_extension(context, "GL_OES_EGL_image_external")) {
      context->api.glEGLImageTargetTexture2DOES = gl.api.glEGLImageTargetTexture2DOES;
   } else {
      wlc_log(WLC_LOG_WARN, "gles2: GL_OES_EGL_image_external not available");
      frag_shader_egl = frag_shader_dummy;
   }

   const struct {
      const char *vert;
      const char *frag;
   } map[PROGRAM_LAST] = {
      { vert_shader, frag_shader_rgb }, // PROGRAM_RGB
      { vert_shader, frag_shader_rgba }, // PROGRAM_RGBA
      { vert_shader, frag_shader_egl }, // PROGRAM_EGL
      { vert_shader, frag_shader_y_uv }, // PROGRAM_Y_UV
      { vert_shader, frag_shader_y_u_v }, // PROGRAM_Y_U_V
      { vert_shader, frag_shader_y_xuxv }, // PROGRAM_Y_XUXV
      { vert_shader, frag_shader_cursor }, // PROGRAM_CURSOR
      { vert_shader, frag_shader_bg }, // PROGRAM_BG
   };

   for (GLuint i = 0; i < PROGRAM_LAST; ++i) {
      GLuint vert = create_shader(map[i].vert, GL_VERTEX_SHADER);
      GLuint frag = create_shader(map[i].frag, GL_FRAGMENT_SHADER);
      context->programs[i].obj = gl.api.glCreateProgram();
      GL_CALL(gl.api.glAttachShader(context->programs[i].obj, vert));
      GL_CALL(gl.api.glAttachShader(context->programs[i].obj, frag));
      GL_CALL(gl.api.glLinkProgram(context->programs[i].obj));
      GL_CALL(gl.api.glDeleteShader(vert));
      GL_CALL(gl.api.glDeleteShader(frag));

      GLint status;
      GL_CALL(gl.api.glGetProgramiv(context->programs[i].obj, GL_LINK_STATUS, &status));
      if (!status) {
         GLsizei len;
         char log[1024];
         GL_CALL(gl.api.glGetProgramInfoLog(context->programs[i].obj, sizeof(log), &len, log));
         wlc_log(WLC_LOG_ERROR, "Linking:\n%*s\n", len, log);
         abort();
      }

      set_program(context, i);
      GL_CALL(gl.api.glBindAttribLocation(context->programs[i].obj, 0, "pos"));
      GL_CALL(gl.api.glBindAttribLocation(context->programs[i].obj, 1, "uv"));

      for (int u = 0; u < UNIFORM_LAST; ++u) {
         context->programs[i].uniforms[u] = GL_CALL(gl.api.glGetUniformLocation(context->programs[i].obj, uniform_names[u]));
      }

      GL_CALL(gl.api.glUniform1i(context->programs[i].uniforms[UNIFORM_TEXTURE0], 0));
      GL_CALL(gl.api.glUniform1i(context->programs[i].uniforms[UNIFORM_TEXTURE1], 1));
      GL_CALL(gl.api.glUniform1i(context->programs[i].uniforms[UNIFORM_TEXTURE2], 2));
   }

   struct {
      GLenum format;
      GLuint w, h;
      GLenum type;
      const void *data;
   } images[TEXTURE_LAST] = {
      { GL_LUMINANCE, 1, 1, GL_UNSIGNED_BYTE, (GLubyte[]){ 0 } }, // TEXTURE_BLACK
Пример #26
0
Файл: x11.c Проект: snells/wlc
static bool
xcb_load(void)
{
   const char *lib = "libxcb.so", *func = NULL;

   if (!(x11.api.xcb_handle = dlopen(lib, RTLD_LAZY))) {
      wlc_log(WLC_LOG_WARN, "%s", dlerror());
      return false;
   }

#define load(x) (x11.api.x = dlsym(x11.api.xcb_handle, (func = #x)))

   if (!load(xcb_flush))
      goto function_pointer_exception;
   if (!load(xcb_connection_has_error))
      goto function_pointer_exception;
   if (!load(xcb_get_setup))
      goto function_pointer_exception;
   if (!load(xcb_setup_roots_iterator))
      goto function_pointer_exception;
   if (!load(xcb_generate_id))
      goto function_pointer_exception;
   if (!load(xcb_create_window_checked))
      goto function_pointer_exception;
   if (!load(xcb_destroy_window))
      goto function_pointer_exception;
   if (!load(xcb_map_window_checked))
      goto function_pointer_exception;
   if (!load(xcb_create_pixmap))
      goto function_pointer_exception;
   if (!load(xcb_create_gc))
      goto function_pointer_exception;
   if (!load(xcb_free_pixmap))
      goto function_pointer_exception;
   if (!load(xcb_free_gc))
      goto function_pointer_exception;
   if (!load(xcb_put_image))
      goto function_pointer_exception;
   if (!load(xcb_create_cursor))
      goto function_pointer_exception;
   if (!load(xcb_free_cursor))
      goto function_pointer_exception;
   if (!load(xcb_change_property))
      goto function_pointer_exception;
   if (!load(xcb_change_window_attributes_checked))
      goto function_pointer_exception;
   if (!load(xcb_intern_atom))
      goto function_pointer_exception;
   if (!load(xcb_intern_atom_reply))
      goto function_pointer_exception;
   if (!load(xcb_request_check))
      goto function_pointer_exception;
   if (!load(xcb_poll_for_event))
      goto function_pointer_exception;
   if (!load(xcb_get_file_descriptor))
      goto function_pointer_exception;
   if (!load(xcb_get_extension_data))
      goto function_pointer_exception;

#undef load

   return true;

function_pointer_exception:
   wlc_log(WLC_LOG_WARN, "Could not load function '%s' from '%s'", func, lib);
   return false;
}
Пример #27
0
Файл: gles2.c Проект: UIKit0/wlc
static bool
gles2_load(void)
{
   const char *lib = "libGLESv2.so", *func = NULL;

   if (!(gl.api.handle = dlopen(lib, RTLD_LAZY))) {
      wlc_log(WLC_LOG_WARN, "%s", dlerror());
      return false;
   }

#define load(x) (gl.api.x = dlsym(gl.api.handle, (func = #x)))

   if (!(load(glGetError)))
      goto function_pointer_exception;
   if (!load(glGetString))
      goto function_pointer_exception;
   if (!load(glEnable))
      goto function_pointer_exception;
   if (!load(glClear))
      goto function_pointer_exception;
   if (!load(glClearColor))
      goto function_pointer_exception;
   if (!load(glViewport))
      goto function_pointer_exception;
   if (!load(glBlendFunc))
      goto function_pointer_exception;
   if (!(load(glCreateShader)))
      goto function_pointer_exception;
   if (!(load(glShaderSource)))
      goto function_pointer_exception;
   if (!(load(glCompileShader)))
      goto function_pointer_exception;
   if (!(load(glDeleteShader)))
      goto function_pointer_exception;
   if (!(load(glGetShaderiv)))
      goto function_pointer_exception;
   if (!(load(glGetShaderInfoLog)))
      goto function_pointer_exception;
   if (!(load(glCreateProgram)))
      goto function_pointer_exception;
   if (!(load(glAttachShader)))
      goto function_pointer_exception;
   if (!(load(glLinkProgram)))
      goto function_pointer_exception;
   if (!(load(glUseProgram)))
      goto function_pointer_exception;
   if (!(load(glDeleteProgram)))
      goto function_pointer_exception;
   if (!(load(glGetProgramiv)))
      goto function_pointer_exception;
   if (!(load(glGetProgramInfoLog)))
      goto function_pointer_exception;
   if (!(load(glEnableVertexAttribArray)))
      goto function_pointer_exception;
   if (!(load(glBindAttribLocation)))
      goto function_pointer_exception;
   if (!(load(glGetUniformLocation)))
      goto function_pointer_exception;
   if (!(load(glUniform1i)))
      goto function_pointer_exception;
   if (!(load(glUniform1fv)))
      goto function_pointer_exception;
   if (!(load(glUniform2fv)))
      goto function_pointer_exception;
   if (!(load(glVertexAttribPointer)))
      goto function_pointer_exception;
   if (!(load(glDrawArrays)))
      goto function_pointer_exception;
   if (!(load(glGenTextures)))
      goto function_pointer_exception;
   if (!(load(glDeleteTextures)))
      goto function_pointer_exception;
   if (!(load(glBindTexture)))
      goto function_pointer_exception;
   if (!(load(glActiveTexture)))
      goto function_pointer_exception;
   if (!(load(glTexParameteri)))
      goto function_pointer_exception;
   if (!(load(glPixelStorei)))
      goto function_pointer_exception;
   if (!(load(glTexImage2D)))
      goto function_pointer_exception;
   if (!(load(glReadPixels)))
      goto function_pointer_exception;

   // Needed for EGL hw surfaces
   load(glEGLImageTargetTexture2DOES);

#undef load

   return true;

function_pointer_exception:
   wlc_log(WLC_LOG_WARN, "Could not load function '%s' from '%s'", func, lib);
   return false;
}
Пример #28
0
Файл: udev.c Проект: Azarn/wlc
static int
input_event(int fd, uint32_t mask, void *data)
{
   (void)fd, (void)mask;
   struct input *input = data;

   if (libinput_dispatch(input->handle) != 0)
      wlc_log(WLC_LOG_WARN, "Failed to dispatch libinput");

   struct libinput_event *event;
   while ((event = libinput_get_event(input->handle))) {
      struct libinput *handle = libinput_event_get_context(event);
      struct libinput_device *device = libinput_event_get_device(event);
      (void)handle;

      switch (libinput_event_get_type(event)) {
         case LIBINPUT_EVENT_DEVICE_ADDED:
            WLC_INTERFACE_EMIT(input.created, device);
            break;

         case LIBINPUT_EVENT_DEVICE_REMOVED:
            WLC_INTERFACE_EMIT(input.destroyed, device);
            break;

         case LIBINPUT_EVENT_POINTER_MOTION:
         {
            struct libinput_event_pointer *pev = libinput_event_get_pointer_event(event);
            struct wlc_input_event ev = {0};
            ev.type = WLC_INPUT_EVENT_MOTION;
            ev.time = libinput_event_pointer_get_time(pev);
            ev.motion.dx = libinput_event_pointer_get_dx(pev);
            ev.motion.dy = libinput_event_pointer_get_dy(pev);
            wl_signal_emit(&wlc_system_signals()->input, &ev);
         }
         break;

         case LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE:
         {
            struct libinput_event_pointer *pev = libinput_event_get_pointer_event(event);
            struct wlc_input_event ev = {0};
            ev.type = WLC_INPUT_EVENT_MOTION_ABSOLUTE;
            ev.time = libinput_event_pointer_get_time(pev);
            ev.motion_abs.x = pointer_abs_x;
            ev.motion_abs.y = pointer_abs_y;
            ev.motion_abs.internal = pev;
            wl_signal_emit(&wlc_system_signals()->input, &ev);
         }
         break;

         case LIBINPUT_EVENT_POINTER_BUTTON:
         {
            struct libinput_event_pointer *pev = libinput_event_get_pointer_event(event);
            struct wlc_input_event ev = {0};
            ev.type = WLC_INPUT_EVENT_BUTTON;
            ev.time = libinput_event_pointer_get_time(pev);
            ev.button.code = libinput_event_pointer_get_button(pev);
            ev.button.state = (enum wl_pointer_button_state)libinput_event_pointer_get_button_state(pev);
            wl_signal_emit(&wlc_system_signals()->input, &ev);
         }
         break;

         case LIBINPUT_EVENT_POINTER_AXIS:
         {
            struct libinput_event_pointer *pev = libinput_event_get_pointer_event(event);
            struct wlc_input_event ev = {0};
            ev.type = WLC_INPUT_EVENT_SCROLL;
            ev.time = libinput_event_pointer_get_time(pev);

#if LIBINPUT_VERSION_MAJOR == 0 && LIBINPUT_VERSION_MINOR < 8
            /* < libinput 0.8.x (at least to 0.6.x) */
            const enum wl_pointer_axis axis = libinput_event_pointer_get_axis(pev);
            ev.scroll.amount[(axis == LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL)] = libinput_event_pointer_get_axis_value(pev);
            ev.scroll.axis_bits |= (axis == LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL ? WLC_SCROLL_AXIS_HORIZONTAL : WLC_SCROLL_AXIS_VERTICAL);
#else
            /* > libinput 0.8.0 */
            if (libinput_event_pointer_has_axis(pev, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL)) {
               ev.scroll.amount[0] = libinput_event_pointer_get_axis_value(pev, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL);
               ev.scroll.axis_bits |= WLC_SCROLL_AXIS_VERTICAL;
            }

            if (libinput_event_pointer_has_axis(pev, LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL)) {
               ev.scroll.amount[1] = libinput_event_pointer_get_axis_value(pev, LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL);
               ev.scroll.axis_bits |= WLC_SCROLL_AXIS_HORIZONTAL;
            }
#endif

            // We should get other axis information from libinput as well, like source (finger, wheel) (v0.8)
            wl_signal_emit(&wlc_system_signals()->input, &ev);
         }
         break;

         case LIBINPUT_EVENT_KEYBOARD_KEY:
         {
            struct libinput_event_keyboard *kev = libinput_event_get_keyboard_event(event);
            struct wlc_input_event ev = {0};
            ev.type = WLC_INPUT_EVENT_KEY;
            ev.time = libinput_event_keyboard_get_time(kev);
            ev.key.code = libinput_event_keyboard_get_key(kev);
            ev.key.state = (enum wl_keyboard_key_state)libinput_event_keyboard_get_key_state(kev);
            ev.device = device;
            wl_signal_emit(&wlc_system_signals()->input, &ev);
         }
         break;

         case LIBINPUT_EVENT_TOUCH_UP:
         {
            struct libinput_event_touch *tev = libinput_event_get_touch_event(event);
            struct wlc_input_event ev = {0};
            ev.type = WLC_INPUT_EVENT_TOUCH;
            ev.time = libinput_event_touch_get_time(tev);
            ev.touch.type = wlc_touch_type_for_libinput_type(libinput_event_get_type(event));
            ev.touch.slot = libinput_event_touch_get_seat_slot(tev);
            wl_signal_emit(&wlc_system_signals()->input, &ev);
         }
         break;

         case LIBINPUT_EVENT_TOUCH_DOWN:
         case LIBINPUT_EVENT_TOUCH_MOTION:
         {
            struct libinput_event_touch *tev = libinput_event_get_touch_event(event);
            struct wlc_input_event ev = {0};
            ev.type = WLC_INPUT_EVENT_TOUCH;
            ev.time = libinput_event_touch_get_time(tev);
            ev.touch.type = wlc_touch_type_for_libinput_type(libinput_event_get_type(event));
            ev.touch.x = touch_abs_x;
            ev.touch.y = touch_abs_y;
            ev.touch.internal = tev;
            ev.touch.slot = libinput_event_touch_get_seat_slot(tev);
            wl_signal_emit(&wlc_system_signals()->input, &ev);
         }
         break;

         case LIBINPUT_EVENT_TOUCH_FRAME:
         case LIBINPUT_EVENT_TOUCH_CANCEL:
         {
            struct libinput_event_touch *tev = libinput_event_get_touch_event(event);
            struct wlc_input_event ev = {0};
            ev.type = WLC_INPUT_EVENT_TOUCH;
            ev.time = libinput_event_touch_get_time(tev);
            ev.touch.type = wlc_touch_type_for_libinput_type(libinput_event_get_type(event));
            wl_signal_emit(&wlc_system_signals()->input, &ev);
         }
         break;

         default: break;
      }

      libinput_event_destroy(event);
   }

   return 0;
}
Пример #29
0
Файл: egl.c Проект: SirCmpwn/wlc
static bool
egl_load(void)
{
   const char *lib = "libEGL.so", *func = NULL;

   if (!(egl.api.handle = dlopen(lib, RTLD_LAZY))) {
      wlc_log(WLC_LOG_WARN, "%s", dlerror());
      return false;
   }

#define load(x) (egl.api.x = dlsym(egl.api.handle, (func = #x)))

   if (!load(eglGetError))
      goto function_pointer_exception;
   if (!load(eglGetDisplay))
      goto function_pointer_exception;
   if (!load(eglInitialize))
      goto function_pointer_exception;
   if (!load(eglTerminate))
      goto function_pointer_exception;
   if (!load(eglQueryString))
      goto function_pointer_exception;
   if (!load(eglChooseConfig))
      goto function_pointer_exception;
   if (!load(eglGetConfigAttrib))
      goto function_pointer_exception;
   if (!load(eglBindAPI))
      goto function_pointer_exception;
   if (!load(eglQueryContext))
      goto function_pointer_exception;
   if (!load(eglCreateContext))
      goto function_pointer_exception;
   if (!load(eglDestroyContext))
      goto function_pointer_exception;
   if (!load(eglCreateWindowSurface))
      goto function_pointer_exception;
   if (!load(eglDestroySurface))
      goto function_pointer_exception;
   if (!load(eglMakeCurrent))
      goto function_pointer_exception;
   if (!load(eglSwapBuffers))
      goto function_pointer_exception;
   if (!load(eglSwapInterval))
      goto function_pointer_exception;
   if (!load(eglGetProcAddress))
      goto function_pointer_exception;

#undef load

#define load(x) (egl.api.x = (void*)egl.api.eglGetProcAddress((func = #x)))

   // EGL surfaces won't work without these
   load(eglCreateImageKHR);
   load(eglDestroyImageKHR);
   load(eglBindWaylandDisplayWL);
   load(eglUnbindWaylandDisplayWL);
   load(eglQueryWaylandBufferWL);

#undef load

   return true;

function_pointer_exception:
   wlc_log(WLC_LOG_WARN, "Could not load function '%s' from '%s'", func, lib);
   return false;
}
Пример #30
0
static bool
open_display(int socks[2])
{
   int lock_fd, dpy = -1;
   char lock_name[64];

retry:
   dpy += 1;
   for (lock_fd = -1; dpy <= 32 && lock_fd < 0; ++dpy) {
      snprintf(lock_name, sizeof(lock_name), LOCK_FMT, dpy);
      if ((lock_fd = open(lock_name, O_WRONLY | O_CREAT | O_EXCL | O_CLOEXEC, 0444)) >= 0)
         break;

      if ((lock_fd = open(lock_name, O_RDONLY | O_CLOEXEC)) < 0)
         continue;

      char pid[12];
      memset(pid, 0, sizeof(pid));
      ssize_t bytes = read(lock_fd, pid, sizeof(pid) - 1);
      close(lock_fd);
      lock_fd = -1;

      if (bytes != sizeof(pid) - 1)
         continue;

      pid_t owner;
      if (!chck_cstr_to_i32(pid, &owner))
         continue;

      /**
       * Check if the pid for existing lock file is not alive by
       * sending kill signal and checking that errno == ESRCH (process not found, in most cases)
       */
      errno = 0;
      if (kill(owner, 0) != 0 && errno == ESRCH) {
         unlink(lock_name);
         snprintf(lock_name, sizeof(lock_name), SOCKET_FMT, dpy);
         unlink(lock_name);

         /* try open again, as the X server for this lock is not running,
          * if we fail here, give up and try next display */
         snprintf(lock_name, sizeof(lock_name), LOCK_FMT, dpy);
         if ((lock_fd = open(lock_name, O_WRONLY | O_CREAT | O_EXCL | O_CLOEXEC, 0444)) >= 0)
            break;
      }
   }

   if (dpy > 32)
      goto no_open_display;

   char pid[12];
   snprintf(pid, sizeof(pid), "%10d", getpid());
   if (write(lock_fd, pid, sizeof(pid) - 1) != sizeof(pid) - 1) {
      unlink(lock_name);
      close(lock_fd);
      goto retry;
   }

   close(lock_fd);

   struct sockaddr_un addr = { .sun_family = AF_LOCAL };
   addr.sun_path[0] = '\0';
   size_t path_size = snprintf(addr.sun_path + 1, sizeof(addr.sun_path) - 1, SOCKET_FMT, dpy);
   if ((socks[0] = open_socket(&addr, path_size)) < 0) {
      unlink(lock_name);
      unlink(addr.sun_path + 1);
      goto retry;
   }

   mkdir(socket_dir, 0777);
   path_size = snprintf(addr.sun_path, sizeof(addr.sun_path), SOCKET_FMT, dpy);
   if ((socks[1] = open_socket(&addr, path_size)) < 0) {
      close(socks[0]);
      unlink(lock_name);
      unlink(addr.sun_path);
      goto retry;
   }

   snprintf(xserver.display_name, sizeof(xserver.display_name), ":%d", (xserver.display = dpy));
   return true;

no_open_display:
   wlc_log(WLC_LOG_WARN, "No open display in first 32");
   goto fail;
fail:
   if (lock_fd > 0) {
      unlink(lock_name);
      close(lock_fd);
   }
   return false;
}